this is my gui, my mcu sometimes stops responding after I waited for a while how do I add some code to pre wake up my MCU serial communication.



import os
import time
import serial.tools.list_ports
import tkinter as tk
import threading
from tkinter import ttk
from tkinter import
from tkinter import filedialog
from tkinter import messagebox
from tkinter.scrolledtext import ScrolledText
os.system(‘clear’) #clear console
thread_running = False
thread_lock = threading.Lock()
################################ declaring global variables ################################
version = ‘1’ #version comparesion require to check with MCU as it connects
device_selected = ‘’ #Com port selects
ser = None #var for communication with MCU
timeout = 1 #timeout timers for connection lost
file_type = ‘’ #identify if IHEX file is used
file_data = ‘’ #otp code pulled from IHEX file
product_data = ‘’ #device code for the device burn setup
validate_data = ‘’ #log data when validating
status = ‘unknown’ #pass or fall
current_directory = os.getcwd() #get current file directory
otp_devices_directory = os.path.join(current_directory, ‘otp_devices’) #go to otp deivces directory
OTP_devices = [] #var for the device list
OTP_devices = os.listdir(otp_devices_directory) #get device lists
OTP_devices = [file[:-4] for file in OTP_devices] #gets rid of the .txt in the device name
CRC_ENABLE = ‘0’ #CRC enable disable
################################ Functons ###################################
#################### check the com port and return a list #####################
def get_ports():
ports = serial.tools.list_ports.comports()
ports_descriptions = [] #create an empty list to store port descriptions
for p in ports:
ports_descriptions.append(p.description) #Add the description to the list
return ports_descriptions
#################### connect the port #####################
def find_port(ports_description):
com_port = ‘None’
numConnection = len(ports_description)
for i in range(0,numConnection):
port = ports_description[i]
strport = str(port)
if ‘OpenSDA’ in strport: #check for Opensda for ports name and autoselect
splitport = strport.split(’ ‘)
com_port_b = splitport[-1]
com_port = com_port_b.strip(“()”)
return com_port
#################### read from MCU uart and decode the message
def read_string(ser, delimiter=b’\r’):
response = b"“
while True:
char = ser.read(1)
if char == delimiter:
break
response += char
return response.decode()
#################### load button function: ##########################
def load_button():
global file_data
global file_type
validate_button.config(state=tk.DISABLED) # Disable the button
burn_button.config(state=tk.DISABLED) # Disable the button
connect_button.config(state=tk.DISABLED) # Disable the button
file_path = tk.filedialog.askopenfilename()
path_list = file_path.split(‘/’)
path_number = len(path_list) - 1
path_display = path_list[path_number]
otp_file[‘text’] = path_display #set displace txt file name
file_name = path_display.replace(‘_’,‘’) #set file type for identification
if ‘IHEX’ in file_name:
log.insert(END,‘IHEX file found\n’)
file_type = ‘IHEX’
else:
messagebox.showinfo(‘warning’,‘can not identify IHEX file’)
return None
with open(file_path, ‘r’) as file: #load data to var
file_data = file.read()
burn_button.config(state=tk.NORMAL) # Enable the button
validate_button.config(state=tk.NORMAL) # Enable the button
connect_button.config(state=tk.NORMAL) # Enable the button
#################### connect button function: #################################
def connect_button():
############### get device info #############
global product_data
global ser
device_selected = device_list.get()
#connect device
if connect_button[‘text’] == ‘Disconnected’:
#if none value selected
if device_selected == ‘’:
messagebox.showinfo(‘warning’,‘No value found in device selection’)
return None
else:
device_selected_directory = os.path.join(otp_devices_directory, device_selected + ‘.txt’)
with open(device_selected_directory, ‘r’) as file: #save the device configure file to product_data
product_data = file.read()
############### connect to device #############
connect_port = find_port(get_ports())
if connect_port != ‘None’:
ser = serial.Serial(connect_port, baudrate = 9600, timeout = 1)
else:
messagebox.showinfo(‘warning’,‘No connection found’)
return None
############### verify mcu code versions #############
ser.write(b’a’)
connect_check = ser.read().decode()
if connect_check == (version): ### check version and check connection ###
log.insert(END,‘device conneted\n’)
connect_button.config(bg=‘#83b079’, text=‘conneted’)
burn_button.config(state=“normal”)
validate_button.config(state=“normal”)
device_list.config(state=“disabled”)
else:
messagebox.showinfo(‘warning’,‘no correct device found\n(please check connected device and check version)’)
return None
else:
############### disconnect device ###############
ser.close()
log.insert(END,‘device disconneted\n’)
connect_button.config(bg=‘#dce3df’, text=‘Disconnected’)
burn_button.config(state=“disabled”)
validate_button.config(state=“disabled”)
device_list.config(state=“normal”)


#################### burn button loop & function: #################################
def burn_button_func():
global product_data
global file_data
global timeout
global CRC_ENABLE
global status
global thread_running
status = ‘pass’ #pass or fall
lines = product_data.splitlines()
OTP_lines = file_data.splitlines()
result.config(text=‘UNKNOW’, bg=‘yellow’)

############## Device info section: ###############
COM_TYPE = lines[lines.index(“Device info:”) + 1].split(”:“)[0] #SPI/I2C
OTP_TYPE = lines[lines.index(“Device info:”) + 1].split(”:“)[1] #MIRROR/DIRECT
BYTE_SIZE = lines[lines.index(“Device info:”) + 2].split(”:“)[1] #BYTE_SIZE
FS_REG = lines[lines.index(“Device info:”) + 3].split(”:“)[1] #FS_REGISTER: YES/NO
CRC = lines[lines.index(“Device info:”) + 4].split(”:“)[1] #CRC: YES/NO
VOTP = lines[lines.index(“Device info:”) + 5].split(”:“)[1] #VOTP: YES/NO
MAIN_I2C_ADDRESS = lines[lines.index(“Device info:”) + 6].split(”:“)[1] #MAIN_I2C_ADDRESS
FAILSAFE_I2C_ADDRESS = lines[lines.index(“Device info:”) + 7].split(”:“)[1] #FAILSAFE_I2C_ADDRESS

############## Ihex info section: ###############
MAIN_OTP_IHEX_START = int(lines[lines.index(“Ihex info:”) + 1].split(”:“)[1]) #MAIN_OTP_IHEX_START_AD
MAIN_OTP_IHEX_END = int(lines[lines.index(“Ihex info:”) + 1].split(”:“)[2]) #MAIN_OTP_IHEX_END_AD
FS_OTP_IHEX_START = int(lines[lines.index(“Ihex info:”) + 2].split(”:“)[1]) #FS_OTP_IHEX_START_AD
FS_OTP_IHEX_END = int(lines[lines.index(“Ihex info:”) + 2].split(”:“)[2]) #FS_OTP_IHEX_START_AD
MAIN_VOTP_IHEX_START = int(lines[lines.index(“Ihex info:”) + 3].split(”:“)[1]) #MAIN_VOTP_IHEX_START_AD
MAIN_VOTP_IHEX_END = int(lines[lines.index(“Ihex info:”) + 3].split(”:“)[2]) #MAIN_VOTP_IHEX_END_AD
FS_VOTP_IHEX_START = int(lines[lines.index(“Ihex info:”) + 4].split(”:“)[1]) #FS_VOTP_IHEX_START_AD
FS_VOTP_IHEX_END = int(lines[lines.index(“Ihex info:”) + 4].split(”:“)[2]) #FS_VOTP_IHEX_END_AD
M_MIRRORCMD = lines[lines.index(“Ihex info:”) + 5].split(”:“)[1] #M_MIRRORCMD_AD
M_MIRRORDATA = lines[lines.index(“Ihex info:”) + 6].split(”:“)[1] #M_MIRRORDATA_AD
FS_MIRRORCMD = lines[lines.index(“Ihex info:”) + 7].split(”:“)[1] #FS_MIRRORCMD_AD
FS_MIRRORDATA = lines[lines.index(“Ihex info:”) + 8].split(”:“)[1] #FS_MIRRORDATA_AD

####################### validation info section #######################
Validate_CMD = lines[lines.index(“validation info:”) + 1].split(”:“)[1] #Validate_CMD
VALIDATION_DATA_FORMAT = lines[lines.index(“validation info:”) + 2].split(”:“)[1] #Validate_DATA_format
MAIN_ADD_START = int(lines[lines.index(“validation info:”) + 3].split(”:“)[1],16) #Main_OTP_ADD_RANGE_START
MAIN_ADD_END = int(lines[lines.index(“validation info:”) + 3].split(”:“)[2],16) #Main_OTP_ADD_RANGE_END
FS_ADD_START = int(lines[lines.index(“validation info:”) + 4].split(”:“)[1],16) #FS_OTP_ADD_RANGE_START
FS_ADD_END = int(lines[lines.index(“validation info:”) + 4].split(”:“)[2],16) #FS_OTP_ADD_RANGE_END
VMAIN_ADD_START = int(lines[lines.index(“validation info:”) + 5].split(”:“)[1],16) #Main_VOTP_ADD_RANGE_START
VMAIN_ADD_END = int(lines[lines.index(“validation info:”) + 5].split(”:“)[2],16) #Main_VOTP_ADD_RANGE_END
VFS_ADD_START = int(lines[lines.index(“validation info:”) + 6].split(”:“)[1],16) #FS_VOTP_ADD_RANGE_START
VFS_ADD_END = int(lines[lines.index(“validation info:”) + 6].split(”:")[2],16) #FS_VOTP_ADD_RANGE_START
####################### byte size #######################
BYTE_SIZE_INT = int(BYTE_SIZE)
ser.write(‘J’.encode(‘utf-8’))
############### CRC_Enable disable check
if CRC ==‘YES’:
CRC_ENABLE = ‘1’ #CRC enable
else:
CRC_ENABLE = ‘0’ #CRC disable
############### send byte number info to MCU ############
ser.write(‘y’.encode(‘utf-8’))
ser.write((BYTE_SIZE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.insert(END,‘start otp burning process\n’)
#########################################################

############## Device Power Up: ################
for line in lines[lines.index(“Power up:”) + 1:lines.index(“Power up complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘Power up process complete\n\n’)
##################################################

############## Test mode entry: ################
for line in lines[lines.index(“Main test mode entry:”) + 1:lines.index(“Main test mode entry complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘Main test mode entry process complete\n\n’)
##################################################

################ save main Ihex value #########################################
for line in OTP_lines[MAIN_OTP_IHEX_START:MAIN_OTP_IHEX_END]:
Byte_count = int((line)[1:3],16)
Starting_ad = (line)[3:7]
Record_type = (line)[7:9]
data = (line)[9:9+Byte_count2]
Check_sum = (line)[9+Byte_count2:9+Byte_count2+2]
##############end check################
if (Record_type == ‘01’): #01 indicate the end
break
for i in range(0, len(data),2):
otp_value = data[i:i+2]
########### sidence controller scheme ############## adding 00 based on BYTE_SIZE
if OTP_TYPE == ‘MIRROR’:
M_MIRRIOR_CMD_length = len(‘01’)
Starting_ad_hex_send = int(Starting_ad, 16) + (i // 2)
required_length = 2 * BYTE_SIZE_INT
otp_add = format(Starting_ad_hex_send, f’0{required_length - M_MIRRIOR_CMD_length}x’)
otp_add = ‘01’ + otp_add
if MAIN_ADD_START <= Starting_ad_hex_send <= MAIN_ADD_END:
if COM_TYPE == ‘SPI’:
signal = ‘m’
ser.write(signal.encode(‘utf-8’))
ser.write((M_MIRRORDATA + ‘;’ + otp_value + ‘;’ + CRC_ENABLE + ‘%’ ).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
ser.write(signal.encode(‘utf-8’))
ser.write((M_MIRRORCMD + ‘;’ + otp_add + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
signal = ‘l’
ser.write(signal.encode(‘utf-8’))
ser.write((MAIN_I2C_ADDRESS+‘;’+ M_MIRRORDATA + ‘;’ + otp_value + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
ser.write(signal.encode(‘utf-8’))
ser.write((MAIN_I2C_ADDRESS+‘;’+ M_MIRRORCMD +‘;’+ otp_add + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
continue
else:
########### non-sidence controller scheme ##############
Starting_ad_hex_send = hex(int(Starting_ad,16) + i // 2)
Starting_ad_int_send = int(Starting_ad, 16) + (i // 2)
otp_add = str(Starting_ad_hex_send).replace(‘0x’, ‘’)
if MAIN_ADD_START <= Starting_ad_int_send <= MAIN_ADD_END:
if COM_TYPE == ‘SPI’:
signal = ‘m’
ser.write(signal.encode(‘utf-8’))
ser.write((otp_add + ‘;’ + otp_value + ‘;’ + CRC_ENABLE + ‘;M%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
signal = ‘l’
ser.write(signal.encode(‘utf-8’))
ser.write((MAIN_I2C_ADDRESS +‘;’+ otp_add + ‘;’ + otp_value + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
continue
log.see(“end”)
log.see(“end”)
log.insert(END,‘Main OTP Ihex loading process complete\n\n’)
############## Config OTP Controller and burn ###############
for line in lines[lines.index(“Config main OTP controller:”) + 1:lines.index(“Config main OTP controller complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘Main OTP burn process complete\n\n’)
############## Burn BE and WP ###############
for line in lines[lines.index(“Burn main OTP BE and WP:”) + 1:lines.index(“Burn main OTP BE and WP complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘Burn main OTP BE and WP process complete\n\n’)
#################################################################################

################ VOTP main ##################################################
if (VOTP != ‘YES’): #01 indicate the end
pass
else:
############## Test mode entry: ################
for line in lines[lines.index(“Main test mode entry:”) + 1:lines.index(“Main test mode entry complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘Main test mode entry process complete\n\n’)
##################################################

################ save main otp Ihex value #################
for line in OTP_lines[MAIN_VOTP_IHEX_START:MAIN_VOTP_IHEX_END]:
Byte_count = int((line)[1:3],16)
Starting_ad = (line)[3:7]
Record_type = (line)[7:9]
data = (line)[9:9+Byte_count2]
Check_sum = (line)[9+Byte_count2:9+Byte_count2+2]
##############end check################
if (Record_type == ‘01’): #01 indicate the end
break
for i in range(0, len(data),2):
otp_value = data[i:i+2]
########### sidence controller scheme ###########
if OTP_TYPE == ‘MIRROR’:
M_VMIRRIOR_CMD_length = len(‘01’)
Starting_ad_hex_send = int(Starting_ad, 16) + (i // 2)
required_length = 2 * BYTE_SIZE_INT
otp_add = format(Starting_ad_hex_send, f’0{required_length - M_VMIRRIOR_CMD_length}x’)
otp_add = ‘01’ + otp_add
if VMAIN_ADD_START <= Starting_ad_hex_send <= VMAIN_ADD_END:
if COM_TYPE == ‘SPI’:
signal = ‘m’
ser.write(signal.encode(‘utf-8’))
ser.write((M_MIRRORDATA + ‘;’ + otp_value + ‘;’ + CRC_ENABLE + ‘%’ ).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
ser.write(signal.encode(‘utf-8’))
ser.write((M_MIRRORCMD + ‘;’ + otp_add + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
signal = ‘l’
ser.write(signal.encode(‘utf-8’))
ser.write((MAIN_I2C_ADDRESS+‘;’+ M_MIRRORDATA + ‘;’ + otp_value + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
ser.write(signal.encode(‘utf-8’))
ser.write((MAIN_I2C_ADDRESS+‘;’+ M_MIRRORCMD +‘;’+ otp_add + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
continue
else:
########### non-sidence controller scheme ##############
Starting_ad_hex_send = hex(int(Starting_ad,16) + i // 2)
Starting_ad_int_send = int(Starting_ad, 16) + (i // 2)
otp_add = str(Starting_ad_hex_send).replace(‘0x’, ‘’)
if VMAIN_ADD_START <= Starting_ad_int_send <= VMAIN_ADD_END:
if COM_TYPE == ‘SPI’:
signal = ‘m’
ser.write(signal.encode(‘utf-8’))
ser.write((otp_add + ‘;’ + otp_value + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
signal = ‘l’
ser.write(signal.encode(‘utf-8’))
ser.write((MAIN_I2C_ADDRESS +‘;’+ otp_add + ‘;’ + otp_value + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
continue
log.see(“end”)
log.see(“end”)
log.insert(END,‘Main VOTP Ihex loading process complete\n\n’)
############## Config OTP Controller and burn ###############
for line in lines[lines.index(“Config main VOTP controller:”) + 1:lines.index(“Config main VOTP controller complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘Main VOTP burn process complete\n\n’)
############## Burn BE and WP ###############
for line in lines[lines.index(“Burn main VOTP BE and WP:”) + 1:lines.index(“Burn main VOTP BE and WP complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘Burn main VOTP BE and WP process complete\n\n’)
#############################################################################


################################### Safety otp ############################################
############## Run Ihex for Safety otp ###############
if (FS_REG != ‘YES’): #01 indicate the end
pass
else:
################### FS test mode entry #################
for line in lines[lines.index(“FS test mode entry:”) + 1:lines.index(“FS test mode entry complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘FS test mode entry process complete\n\n’)
######################################################

################ save FS Ihex value #################
for line in OTP_lines[FS_OTP_IHEX_START:FS_OTP_IHEX_END]:
Byte_count = int((line)[1:3],16)
Starting_ad = (line)[3:7]
Record_type = (line)[7:9]
data = (line)[9:9+Byte_count2]
Check_sum = (line)[9+Byte_count2:9+Byte_count2+2]
##############end check################
if (Record_type == ‘01’): #01 indicate the end
break
for i in range(0, len(data),2):
otp_value = data[i:i+2]
########### start sending OTP burning code ##############
if OTP_TYPE == ‘MIRROR’:
M_MIRRIOR_CMD_length = len(‘01’)
Starting_ad_hex_send = int(Starting_ad, 16) + (i // 2)
required_length = 2 * BYTE_SIZE_INT
otp_add = format(Starting_ad_hex_send, f’0{required_length - M_MIRRIOR_CMD_length}x’)
otp_add = ‘01’ + otp_add
if FS_ADD_START <= Starting_ad_hex_send <= FS_ADD_END:
if COM_TYPE == ‘SPI’:
signal = ‘m’
ser.write(signal.encode(‘utf-8’))
ser.write((FS_MIRRORDATA + ‘;’ + otp_value + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
ser.write(signal.encode(‘utf-8’))
ser.write((FS_MIRRORCMD +‘;’+ otp_add + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
signal = ‘l’
ser.write(signal.encode(‘utf-8’))
ser.write((FAILSAFE_I2C_ADDRESS +‘;’ + FS_MIRRORDATA + ‘;’ + otp_value + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
ser.write(signal.encode(‘utf-8’))
ser.write((FAILSAFE_I2C_ADDRESS + ‘;’ + FS_MIRRORCMD +‘;’+ otp_add + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
continue
else:
Starting_ad_hex_send = hex(int(Starting_ad,16) + i//2)
otp_add = str(Starting_ad_hex_send).replace(‘0x’, ‘’)
if FS_ADD_START <= Starting_ad_hex_send <= FS_ADD_END:
if COM_TYPE == ‘SPI’:
signal = ‘m’
ser.write(signal.encode(‘utf-8’))
ser.write((otp_value + ‘;’ + otp_add + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
signal = ‘l’
ser.write(signal.encode(‘utf-8’))
ser.write((FAILSAFE_I2C_ADDRESS + ‘;’ + otp_add + ‘；’ + otp_value + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
continue
log.see(“end”)
log.insert(END,‘FS OTP Ihex loading process complete\n\n’)
############## config FS OTP controller and burn ###############
for line in lines[lines.index(“Config FS OTP controller:”) + 1:lines.index(“Config FS OTP controller complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘FS OTP burn process complete\n\n’)
############## Burn FS BE and WP ###############
for line in lines[lines.index(“Burn FS OTP BE and WP:”) + 1:lines.index(“Burn FS OTP BE and WP complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘Burn FS OTP BE and WP process complete\n\n’)
################## VOTP FS ##################
if (VOTP != ‘YES’):
pass
else:
################### FS test mode entry #################
for line in lines[lines.index(“FS test mode entry:”) + 1:lines.index(“FS test mode entry complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘FS test mode entry process complete\n\n’)
################################################################
for line in OTP_lines[FS_VOTP_IHEX_START:FS_VOTP_IHEX_END]:
Byte_count = int((line)[1:3],16)
Starting_ad = (line)[3:7]
Record_type = (line)[7:9]
data = (line)[9:9+Byte_count2]
Check_sum = (line)[9+Byte_count2:9+Byte_count2+2]
##############end check################
if (Record_type == ‘01’): #01 indicate the end
break
for i in range(0, len(data),2):
otp_value = data[i:i+2]
########### sidence controller scheme ###########
if OTP_TYPE == ‘MIRROR’:
FS_VMIRRIOR_CMD_length = len(‘01’)
Starting_ad_hex_send = int(Starting_ad, 16) + (i // 2)
required_length = 2 * BYTE_SIZE_INT
otp_add = format(Starting_ad_hex_send, f’0{required_length - FS_VMIRRIOR_CMD_length}x’)
otp_add = ‘01’ + otp_add
if VFS_ADD_START <= Starting_ad_hex_send <= VFS_ADD_END:
if COM_TYPE == ‘SPI’:
signal = ‘m’
ser.write(signal.encode(‘utf-8’))
ser.write((FS_MIRRORDATA + ‘;’ + otp_value + ‘;’ + CRC_ENABLE + ‘%’ ).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
ser.write(signal.encode(‘utf-8’))
ser.write((FS_MIRRORCMD + ‘;’ + otp_add + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
signal = ‘l’
ser.write(signal.encode(‘utf-8’))
ser.write((FAILSAFE_I2C_ADDRESS+‘;’+ FS_MIRRORDATA + ‘;’ + otp_value + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
ser.write(signal.encode(‘utf-8’))
ser.write((FAILSAFE_I2C_ADDRESS+‘;’+ FS_MIRRORCMD +‘;’+ otp_add + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
continue
else:
########### non-sidence controller scheme ##############
Starting_ad_hex_send = hex(int(Starting_ad,16) + i // 2)
Starting_ad_int_send = int(Starting_ad, 16) + (i // 2)
otp_add = str(Starting_ad_hex_send).replace(‘0x’, ‘’)
if VFS_ADD_START <= Starting_ad_int_send <= VFS_ADD_END:
if COM_TYPE == ‘SPI’:
signal = ‘m’
ser.write(signal.encode(‘utf-8’))
ser.write((otp_add + ‘;’ + otp_value + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
signal = ‘l’
ser.write(signal.encode(‘utf-8’))
ser.write((FAILSAFE_I2C_ADDRESS +‘;’+ otp_add + ‘;’ + otp_value + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
else:
continue
log.see(“end”)
log.insert(END,‘FS VOTP Ihex loading process complete\n\n’)
############## config FS OTP controller and burn ###############
for line in lines[lines.index(“Config FS VOTP controller:”) + 1:lines.index(“Config FS VOTP controller complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘FS VOTP burn process complete\n\n’)
##################### Burn FS BE and WP #######################
for line in lines[lines.index(“Burn FS VOTP BE and WP:”) + 1:lines.index(“Burn FS VOTP BE and WP complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘Burn FS VOTP BE and WP process complete\n\n’)
#################################################################

############## Shutdown: ###############
for line in lines[lines.index(“Shutdown:”) + 1:lines.index(“End:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
########################## add later ################################
ser.write(b’z’) #deactivate device
log.insert(END,‘Device shutdown\n\n’)
######################### restart and validate ######################
log.insert(END,‘\n\n\n’)
validate_button_func()



################### validation button function: #################################
def validate_button_func():
global product_data
global file_data
global status
global thread_running
status = ‘pass’
#read lines between Setup and Powerup
lines = product_data.splitlines()
OTP_lines = file_data.splitlines()
result.config(text=‘UNKNOW’, bg=‘yellow’)
############## Device info section: ###############
COM_TYPE = lines[lines.index(“Device info:”) + 1].split(“:”)[0] #SPI/I2C
OTP_TYPE = lines[lines.index(“Device info:”) + 1].split(“:”)[1] #MIRROR/DIRECT
BYTE_SIZE = lines[lines.index(“Device info:”) + 2].split(“:”)[1] #BYTE_SIZE
FS_REG = lines[lines.index(“Device info:”) + 3].split(“:”)[1] #FS_REGISTER: YES/NO
CRC = lines[lines.index(“Device info:”) + 4].split(“:”)[1] #CRC: YES/NO
VOTP = lines[lines.index(“Device info:”) + 5].split(“:”)[1] #VOTP: YES/NO
MAIN_I2C_ADDRESS = lines[lines.index(“Device info:”) + 6].split(“:”)[1] #MAIN_I2C_ADDRESS
FAILSAFE_I2C_ADDRESS = lines[lines.index(“Device info:”) + 7].split(“:”)[1] #FAILSAFE_I2C_ADDRESS

############## Ihex info section: ###############
MAIN_OTP_IHEX_START = int(lines[lines.index(“Ihex info:”) + 1].split(“:”)[1]) #MAIN_OTP_IHEX_START_AD
MAIN_OTP_IHEX_END = int(lines[lines.index(“Ihex info:”) + 1].split(“:”)[2]) #MAIN_OTP_IHEX_END_AD
FS_OTP_IHEX_START = int(lines[lines.index(“Ihex info:”) + 2].split(“:”)[1]) #FS_OTP_IHEX_START_AD
FS_OTP_IHEX_END = int(lines[lines.index(“Ihex info:”) + 2].split(“:”)[2]) #FS_OTP_IHEX_START_AD
MAIN_VOTP_IHEX_START = int(lines[lines.index(“Ihex info:”) + 3].split(“:”)[1]) #MAIN_VOTP_IHEX_START_AD
MAIN_VOTP_IHEX_END = int(lines[lines.index(“Ihex info:”) + 3].split(“:”)[2]) #MAIN_VOTP_IHEX_END_AD
FS_VOTP_IHEX_START = int(lines[lines.index(“Ihex info:”) + 4].split(“:”)[1]) #FS_VOTP_IHEX_START_AD
FS_VOTP_IHEX_END = int(lines[lines.index(“Ihex info:”) + 4].split(“:”)[2]) #FS_VOTP_IHEX_END_AD
M_MIRRORCMD = lines[lines.index(“Ihex info:”) + 5].split(“:”)[1] #M_MIRRORCMD_AD
M_MIRRORDATA = lines[lines.index(“Ihex info:”) + 6].split(“:”)[1] #M_MIRRORDATA_AD
FS_MIRRORCMD = lines[lines.index(“Ihex info:”) + 7].split(“:”)[1] #FS_MIRRORCMD_AD
FS_MIRRORDATA = lines[lines.index(“Ihex info:”) + 8].split(“:”)[1] #FS_MIRRORDATA_AD

####################### validation info section #######################
Validate_CMD = lines[lines.index(“validation info:”) + 1].split(“:”)[1] #Validate_CMD
VALIDATION_DATA_FORMAT = lines[lines.index(“validation info:”) + 2].split(“:”)[1] #Validate_DATA_format
MAIN_ADD_START = int(lines[lines.index(“validation info:”) + 3].split(“:”)[1],16) #Main_OTP_ADD_RANGE_START
MAIN_ADD_END = int(lines[lines.index(“validation info:”) + 3].split(“:”)[2],16) #Main_OTP_ADD_RANGE_END
FS_ADD_START = int(lines[lines.index(“validation info:”) + 4].split(“:”)[1],16) #FS_OTP_ADD_RANGE_START
FS_ADD_END = int(lines[lines.index(“validation info:”) + 4].split(“:”)[2],16) #FS_OTP_ADD_RANGE_END
VMAIN_ADD_START = int(lines[lines.index(“validation info:”) + 5].split(“:”)[1],16) #Main_VOTP_ADD_RANGE_START
VMAIN_ADD_END = int(lines[lines.index(“validation info:”) + 5].split(“:”)[2],16) #Main_VOTP_ADD_RANGE_END
VFS_ADD_START = int(lines[lines.index(“validation info:”) + 6].split(“:”)[1],16) #FS_VOTP_ADD_RANGE_START
VFS_ADD_END = int(lines[lines.index(“validation info:”) + 6].split(“:”)[2],16) #FS_VOTP_ADD_RANGE_START
####################### byte size #######################
BYTE_SIZE_INT = int(BYTE_SIZE)
ser.write(‘J’.encode(‘utf-8’))
############### CRC_Enable disable check
if CRC ==‘YES’:
CRC_ENABLE = ‘1’ #CRC enable
else:
CRC_ENABLE = ‘0’ #CRC disable
#####send byte size#######
ser.write(‘y’.encode(‘utf-8’))
ser.write((BYTE_SIZE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.insert(END,‘start otp validating process\n’)
##################################################

############## Device Power Up: ################
for line in lines[lines.index(“Power up:”) + 1:lines.index(“Power up complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘Power up process complete\n\n’)
##################################################

############## Test mode entry: ################
for line in lines[lines.index(“Main test mode entry:”) + 1:lines.index(“Main test mode entry complete:”)]:
setup = line.split(‘/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘Main test mode entry process complete\n\n’)
##################################################

######################## Run Ihex validation for main otp ###########################
log.insert(END,‘valitaion starting\n’)
if (VOTP != ‘YES’): #01 indicate the end
pass
else:
for line in OTP_lines[MAIN_VOTP_IHEX_START:MAIN_VOTP_IHEX_END]:
Byte_count = int((line)[1:3],16)
Starting_ad = (line)[3:7]
Record_type = (line)[7:9]
data = (line)[9:9+Byte_count2]
Check_sum = (line)[9+Byte_count2:9+Byte_count2+2]
##############end check################
if (Record_type == ‘01’): #01 indicate the end of the Ihex
break
for i in range(0, len(data),2):
otp_value = data[i:i+2]
########### start otp validate code ##############
if OTP_TYPE == ‘MIRROR’:
Validate_CMD_length = len(Validate_CMD)
Starting_ad_hex_send = int(Starting_ad, 16) + (i // 2)
required_length = 2 * BYTE_SIZE_INT
otp_add = format(Starting_ad_hex_send, f’0{required_length - Validate_CMD_length}x’)
otp_add = Validate_CMD + otp_add
if VMAIN_ADD_START <= Starting_ad_hex_send <= VMAIN_ADD_END:
########### read data #######################
if COM_TYPE == ‘SPI’:
signal = ‘m’
ser.write(signal.encode(‘utf-8’))
ser.write((M_MIRRORCMD + ‘;’ + otp_add + ‘;’ + CRC_ENABLE +‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
else:
signal = ‘l’
ser.write(signal.encode(‘utf-8’))
ser.write((MAIN_I2C_ADDRESS + ‘;’ + M_MIRRORCMD + ‘;’ + otp_add + ‘;’ + CRC_ENABLE +‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
########### check read #######################
if COM_TYPE == ‘SPI’:
signal = ‘o’
ser.write(signal.encode(‘utf-8’))
ser.write((M_MIRRORDATA +‘;’+ CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
check = compare_values(otp_value.lower(), extract_value(respond), VALIDATION_DATA_FORMAT)
if check:
log.insert(END,‘Correct, ’ + respond + ‘\n’)
else:
log.insert(END,‘Error, ’ + respond + ‘\n’)
status = ‘fail’
result.config(text=‘FAIL’, bg=‘red’)
log.update_idletasks()
log.see(“end”)
else:
signal = ‘n’
ser.write(signal.encode(‘utf-8’))
ser.write((MAIN_I2C_ADDRESS + ‘;’ + M_MIRRORDATA + ‘;’ + CRC_ENABLE +’%’).encode(‘utf-8’))
respond = read_string(ser)
check = compare_values(otp_value.lower(), extract_value(respond), VALIDATION_DATA_FORMAT)
if check:
log.insert(END,‘Correct, ’ + respond + ‘\n’)
else:
log.insert(END,‘Error, ’ + respond + ‘\n’)
status = ‘fail’
result.config(text=‘FAIL’, bg=‘red’)
log.update_idletasks()
log.see(“end”)
else:
continue
else:
########### non-sidence controller scheme ##############
Starting_ad_hex_send = hex(int(Starting_ad, 16) + i // 2)
Starting_ad_int_send = int(Starting_ad, 16) + (i // 2)
otp_add = str(Starting_ad_hex_send).replace(‘0x’, ‘’)
########### check read #######################
if VMAIN_ADD_START <= Starting_ad_int_send <= VMAIN_ADD_END:
if COM_TYPE == ‘SPI’:
signal = ‘o’
ser.write(signal.encode(‘utf-8’))
ser.write((otp_add +’;’+ CRC_ENABLE +‘%’).encode(‘utf-8’))
respond = read_string(ser)
check = compare_values(otp_value.lower(), extract_value(respond), VALIDATION_DATA_FORMAT)
if check:
log.insert(END,‘Correct, ’ + respond + ‘\n’)
else:
log.insert(END,‘Error, ’ + respond + ‘\n’)
status = ‘fail’
result.config(text=‘FAIL’, bg=‘red’)
log.update_idletasks()
log.see(“end”)
else:
signal = ‘n’
ser.write(signal.encode(‘utf-8’))
ser.write((MAIN_I2C_ADDRESS + ‘;’ + otp_add +’;’+ CRC_ENABLE +‘%’).encode(‘utf-8’))
respond = read_string(ser)
check = compare_values(otp_value.lower(), extract_value(respond), VALIDATION_DATA_FORMAT)
if check:
log.insert(END,‘Correct, ’ + respond + ‘\n’)
else:
log.insert(END,‘Error, ’ + respond + ‘\n’)
status = ‘fail’
result.config(text=‘FAIL’, bg=‘red’)
log.update_idletasks()
log.see(“end”)
else:
continue
log.see(“end”)
log.insert(END,‘main VOTP check complete\n\n’)
for line in OTP_lines[MAIN_OTP_IHEX_START:MAIN_OTP_IHEX_END]:
Byte_count = int((line)[1:3],16)
Starting_ad = (line)[3:7]
Record_type = (line)[7:9]
data = (line)[9:9+Byte_count2]
Check_sum = (line)[9+Byte_count2:9+Byte_count2+2]
##############end check################
if (Record_type == ‘01’): #01 indicate the end of the Ihex
break
for i in range(0, len(data),2):
otp_value = data[i:i+2]
########### start otp validate code ##############
if OTP_TYPE == ‘MIRROR’:
Validate_CMD_length = len(Validate_CMD)
Starting_ad_hex_send = int(Starting_ad, 16) + (i // 2)
required_length = 2 * BYTE_SIZE_INT
otp_add = format(Starting_ad_hex_send, f’0{required_length - Validate_CMD_length}x’)
otp_add = Validate_CMD + otp_add
if MAIN_ADD_START <= Starting_ad_hex_send <= MAIN_ADD_END:
########### read data #######################
if COM_TYPE == ‘SPI’:
signal = ‘m’
ser.write(signal.encode(‘utf-8’))
ser.write((M_MIRRORCMD + ‘;’ + otp_add + ‘;’ + CRC_ENABLE +‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
else:
signal = ‘l’
ser.write(signal.encode(‘utf-8’))
ser.write((MAIN_I2C_ADDRESS + ‘;’ + M_MIRRORCMD + ‘;’ + otp_add + ‘;’ + CRC_ENABLE +‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
########### check read #######################
if COM_TYPE == ‘SPI’:
signal = ‘o’
ser.write(signal.encode(‘utf-8’))
ser.write((M_MIRRORDATA +‘;’+ CRC_ENABLE +‘%’).encode(‘utf-8’))
respond = read_string(ser)
check = compare_values(otp_value.lower(), extract_value(respond), VALIDATION_DATA_FORMAT)
if check:
log.insert(END,‘Correct, ’ + respond + ‘\n’)
else:
log.insert(END,‘Error, ’ + respond + ‘\n’)
status = ‘fail’
result.config(text=‘FAIL’, bg=‘red’)
log.update_idletasks()
log.see(“end”)
else:
signal = ‘n’
ser.write(signal.encode(‘utf-8’))
ser.write((MAIN_I2C_ADDRESS + ‘;’ + M_MIRRORDATA + ‘;’ + CRC_ENABLE +’%’).encode(‘utf-8’))
respond = read_string(ser)
check = compare_values(otp_value.lower(), extract_value(respond), VALIDATION_DATA_FORMAT)
if check:
log.insert(END,‘Correct, ’ + respond + ‘\n’)
else:
log.insert(END,‘Error, ’ + respond + ‘\n’)
status = ‘fail’
result.config(text=‘FAIL’, bg=‘red’)
log.update_idletasks()
log.see(“end”)
else:
continue
else:
########### non-sidence controller scheme ##############
Starting_ad_hex_send = hex(int(Starting_ad, 16) + i // 2)
Starting_ad_int_send = int(Starting_ad, 16) + (i // 2)
otp_add = str(Starting_ad_hex_send).replace(‘0x’, ‘’)
########### check read #######################
if MAIN_ADD_START <= Starting_ad_int_send <= MAIN_ADD_END:
if COM_TYPE == ‘SPI’:
signal = ‘o’
ser.write(signal.encode(‘utf-8’))
ser.write((otp_add +’;’+ CRC_ENABLE +‘%’).encode(‘utf-8’))
respond = read_string(ser)
check = compare_values(otp_value.lower(), extract_value(respond), VALIDATION_DATA_FORMAT)
if check:
log.insert(END,‘Correct, ’ + respond + ‘\n’)
else:
log.insert(END,‘Error, ’ + respond + ‘\n’)
status = ‘fail’
result.config(text=‘FAIL’, bg=‘red’)
log.update_idletasks()
log.see(“end”)
else:
signal = ‘n’
ser.write(signal.encode(‘utf-8’))
ser.write((MAIN_I2C_ADDRESS + ‘;’ + otp_add +’;’+ CRC_ENABLE +‘%’).encode(‘utf-8’))
respond = read_string(ser)
check = compare_values(otp_value.lower(), extract_value(respond), VALIDATION_DATA_FORMAT)
if check:
log.insert(END,‘Correct, ’ + respond + ‘\n’)
else:
log.insert(END,‘Error, ’ + respond + ‘\n’)
status = ‘fail’
result.config(text=‘FAIL’, bg=‘red’)
log.update_idletasks()
log.see(“end”)
else:
continue
log.see(“end”)
log.insert(END,‘main OTP check complete\n\n’)
############## checking SAFETY REG is needed ###############
if (FS_REG != ‘YES’): #01 indicate the end
pass
else:
################### FS test mode entry #################
for line in lines[lines.index(“FS test mode entry:”) + 1:lines.index(“FS test mode entry complete:”)]:
setup = line.split(’/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1] + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘FS test mode entry process complete\n\n’)
######################## Run Ihex validation for FS otp ##############################
if (VOTP != ‘YES’): #01 indicate the end
pass
else:
for line in OTP_lines[FS_VOTP_IHEX_START:FS_VOTP_IHEX_END]:
Byte_count = int((line)[1:3],16)
Starting_ad = (line)[3:7]
Record_type = (line)[7:9]
data = (line)[9:9+Byte_count2]
Check_sum = (line)[9+Byte_count2:9+Byte_count2+2]
##############end check################
if (Record_type == ‘01’): #01 indicate the end of the Ihex
break
for i in range(0, len(data),2):
otp_value = data[i:i+2]
########### start otp validate code ##############
if OTP_TYPE == ‘MIRROR’:
Validate_CMD_length = len(Validate_CMD)
Starting_ad_hex_send = int(Starting_ad, 16) + (i // 2)
required_length = 2 * BYTE_SIZE_INT
otp_add = format(Starting_ad_hex_send, f’0{required_length - Validate_CMD_length}x’)
otp_add = Validate_CMD + otp_add
if VFS_ADD_START <= Starting_ad_hex_send <= VFS_ADD_END:
########### read data #######################
if COM_TYPE == ‘SPI’:
signal = ‘m’
ser.write(signal.encode(‘utf-8’))
ser.write((FS_MIRRORCMD + ‘;’ + otp_add + ‘;’ + CRC_ENABLE +’%‘).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
else:
signal = ‘l’
ser.write(signal.encode(‘utf-8’))
ser.write((FAILSAFE_I2C_ADDRESS + ‘;’ + FS_MIRRORCMD + ‘;’ + otp_add + ‘;’ + CRC_ENABLE +’%‘).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
########### check read #######################
if COM_TYPE == ‘SPI’:
signal = ‘o’
ser.write(signal.encode(‘utf-8’))
ser.write((FS_MIRRORDATA +’;‘+ CRC_ENABLE +’%‘).encode(‘utf-8’))
respond = read_string(ser)
check = compare_values(otp_value.lower(), extract_value(respond), VALIDATION_DATA_FORMAT)
if check:
log.insert(END,‘Correct, ’ + respond + ‘\n’)
else:
log.insert(END,‘Error, ’ + respond + ‘\n’)
status = ‘fail’
result.config(text=‘FAIL’, bg=‘red’)
log.update_idletasks()
log.see(“end”)
else:
signal = ‘n’
ser.write(signal.encode(‘utf-8’))
ser.write((FAILSAFE_I2C_ADDRESS + ‘;’ + FS_MIRRORDATA + ‘;’ + CRC_ENABLE +’%’).encode(‘utf-8’))
respond = read_string(ser)
check = compare_values(otp_value.lower(), extract_value(respond), VALIDATION_DATA_FORMAT)
if check:
log.insert(END,‘Correct, ’ + respond + ‘\n’)
else:
log.insert(END,‘Error, ’ + respond + ‘\n’)
status = ‘fail’
result.config(text=‘FAIL’, bg=‘red’)
log.update_idletasks()
log.see(“end”)
else:
continue
else:
########### non-sidence controller scheme ##############
Starting_ad_hex_send = hex(int(Starting_ad, 16) + i // 2)
Starting_ad_int_send = int(Starting_ad, 16) + (i // 2)
otp_add = str(Starting_ad_hex_send).replace(‘0x’, ‘’)
########### check read #######################
if VFS_ADD_START <= Starting_ad_int_send <= VFS_ADD_END:
if COM_TYPE == ‘SPI’:
signal = ‘o’
ser.write(signal.encode(‘utf-8’))
ser.write((otp_add +’;’+ CRC_ENABLE +’%‘).encode(‘utf-8’))
respond = read_string(ser)
check = compare_values(otp_value.lower(), extract_value(respond), VALIDATION_DATA_FORMAT)
if check:
log.insert(END,‘Correct, ’ + respond + ‘\n’)
else:
log.insert(END,‘Error, ’ + respond + ‘\n’)
status = ‘fail’
result.config(text=‘FAIL’, bg=‘red’)
log.update_idletasks()
log.see(“end”)
else:
signal = ‘n’
ser.write(signal.encode(‘utf-8’))
ser.write((FAILSAFE_I2C_ADDRESS + ‘;’ + otp_add +’;’+ CRC_ENABLE +’%‘).encode(‘utf-8’))
respond = read_string(ser)
check = compare_values(otp_value.lower(), extract_value(respond), VALIDATION_DATA_FORMAT)
if check:
log.insert(END,‘Correct, ’ + respond + ‘\n’)
else:
log.insert(END,‘Error, ’ + respond + ‘\n’)
status = ‘fail’
result.config(text=‘FAIL’, bg=‘red’)
log.update_idletasks()
log.see(“end”)
else:
continue
log.see(“end”)
log.insert(END,‘FS VOTP check complete\n\n’)
for line in OTP_lines[FS_OTP_IHEX_START:FS_OTP_IHEX_END]:
Byte_count = int((line)[1:3],16)
Starting_ad = (line)[3:7]
Record_type = (line)[7:9]
data = (line)[9:9 + Byte_count2]
Check_sum = (line)[9 + Byte_count2:9 + Byte_count*2 + 2]
##############end check################
if (Record_type == ‘01’): #01 indicate the end
break
for i in range(0, len(data),2):
otp_value = data[i:i + 2]
########### start otp validate code ##############
if OTP_TYPE == ‘MIRROR’:
FS_MIRRIOR_CMD_length = len(Validate_CMD)
Starting_ad_hex_send = int(Starting_ad, 16) + (i // 2)
required_length = 2 * BYTE_SIZE_INT
otp_add = format(Starting_ad_hex_send, f’0{required_length - FS_MIRRIOR_CMD_length}x’)
otp_add = Validate_CMD + otp_add
if FS_ADD_START <= Starting_ad_hex_send <= FS_ADD_END:
########### read data #######################
if COM_TYPE == ‘SPI’:
signal = ‘m’
ser.write(signal.encode(‘utf-8’))
ser.write((FS_MIRRORCMD + ‘;’ + otp_add + ‘;’ + CRC_ENABLE +’%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
else:
signal = ‘l’
ser.write(signal.encode(‘utf-8’))
ser.write((FAILSAFE_I2C_ADDRESS + ‘;’ + FS_MIRRORCMD + ‘;’ + otp_add + ‘;’ + CRC_ENABLE +‘%’).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
########### check read #######################
if COM_TYPE == ‘SPI’:
signal = ‘o’
ser.write(signal.encode(‘utf-8’))
ser.write((FS_MIRRORDATA + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
check = compare_values(otp_value.lower(), extract_value(respond), VALIDATION_DATA_FORMAT)
if check:
log.insert(END,‘Correct, ’ + respond + ‘\n’)
else:
log.insert(END,‘Error,’ + respond + ‘\n’)
status = ‘fail’
result.config(text=‘FAIL’, bg=‘red’)
log.update_idletasks()
log.see(“end”)
else:
signal = ‘n’
ser.write(signal.encode(‘utf-8’))
ser.write((FAILSAFE_I2C_ADDRESS + ‘;’ + FS_MIRRORDATA + ‘;’ + CRC_ENABLE + ‘%’).encode(‘utf-8’))
respond = read_string(ser)
check = compare_values(otp_value.lower(), extract_value(respond), VALIDATION_DATA_FORMAT)
if check:
log.insert(END,‘Correct, ’ + respond + ‘\n’)
else:
log.insert(END,‘Error, ’ + respond + ‘\n’)
status = ‘fail’
result.config(text=‘FAIL’, bg=‘red’)
log.update_idletasks()
log.see(“end”)
else:
continue
else:
log.insert(END,‘PF product currently not implemented\n\n’)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
log.insert(END,‘FS OTP check complete\n\n’)

############## check result: ###############
if status == ‘pass’:
result.config(text=‘PASS’, bg=‘green’)
else:
result.config(text=‘FAIL’, bg=‘red’)
############## Shutdown: ###############
for line in lines[lines.index(“Shutdown:”) + 1:lines.index(“End:”)]:
setup = line.split(’/’)
ser.write(setup[0].encode(‘utf-8’))
ser.write((setup[1]+’%‘).encode(‘utf-8’))
respond = read_string(ser)
log.insert(END,respond)
log.update_idletasks()
log.see(“end”)
log.see(“end”)
ser.write(b’z’) #deactivate device
log.insert(END,‘Device shutdown\n\n’)
thread_running = False #stop threading
burn_button.config(state=tk.NORMAL) # Enable the button
validate_button.config(state=tk.NORMAL) # Enable the button
load_button.config(state=tk.NORMAL) # Enable the button
connect_button.config(state=tk.NORMAL) # Enable the button
#######################END#####################


################# extract the returned readback value ############
def extract_value(received_string):
# Split the received string by whitespace and ‘0x’
parts = received_string.split()
# Initialize variables to keep track of the count and extracted value
count = 0
extracted_value = None
# Iterate through the parts to find the value following the second “0x”
for part in parts:
if “0x” in part:
count += 1
if count == 2:
extracted_value = part.replace(“0x”, “”)[:10] # Extract the next four characters
break
return extracted_value
################# compare the value of readback and otp ############
def compare_values(otp_value, readback_value, reading_format):
# Ensure reading_format is the same length as the readback_value
if len(reading_format) != len(readback_value):
print(“Length of reading_format must match the length of readback_value.”)
return False
# Iterate through the format and compare accordingly
check_value_index = 0
for i, char in enumerate(reading_format):
if char == ‘d’: # Compare only the ‘dd’ parts
if check_value_index >= len(otp_value) or otp_value[check_value_index] != readback_value[i]:
return False
check_value_index += 1 # Move to the next character in otp_value
elif char == ‘x’: # Ignore the ‘xx’ parts
continue
else:
print(“Invalid character in reading_format. Use ‘d’ for compare and ‘x’ for ignore.”)
return False

return check_value_index == len(otp_value) # Ensure all of otp_value was used
################# burn button add threading ############
def burn_button_func_threading():
global thread_running
with thread_lock:
if not thread_running:
thread_running = True
validate_button.config(state=tk.DISABLED) # Disable the butto
burn_button.config(state=tk.DISABLED) # Disable the button
load_button.config(state=tk.DISABLED) # Disable the button
connect_button.config(state=tk.DISABLED) # Disable the button
t = threading.Thread(target=burn_button_func)
t.start()
################# validation buttion add threading ############
def validate_button_func_threading():
global thread_running
with thread_lock:
if not thread_running:
thread_running = True
validate_button.config(state=tk.DISABLED) # Disable the butto
burn_button.config(state=tk.DISABLED) # Disable the button
load_button.config(state=tk.DISABLED) # Disable the button
connect_button.config(state=tk.DISABLED) # Disable the button
t = threading.Thread(target=validate_button_func)
t.start()
################# clear log ############
def clear_log_button():
log.delete(1.0, tk.END)
################ save log to a txt file #################
def save_log_button():
file_path = tk.filedialog.askopenfilename()
with open(file_path, ‘w’) as file: #save the device configure file to product_data
file.write(log.get(1.0, tk.END))

####################
# Tkinter GUI
####################
window = tk.Tk()
window.title(‘NXP’)
window.iconbitmap(‘NXPICO.ico’)
window.geometry(‘250x260’)
window.resizable(width=False, height=False)
#tk variables
log_string = tk.StringVar()
#main frames(seperate window to 4 frames)
input_frame = ttk.Frame(window)
operate_frame = ttk.Frame(window)
recording_frame = ttk.Frame(window)
result_frame = ttk.Frame(window)
#main frame layout(layout for these 4 frames)
input_frame.place(x = 5, y = 0, relwidth = 0.96, relheight = 0.3)
operate_frame.place(x = 5, rely = 0.3, relwidth = 0.96, relheight = 0.1)
recording_frame.place(x = 5, rely = 0.4, relwidth = 0.96, relheight = 0.5)
result_frame.place(x = 5, rely = 0.88, relwidth = 0.96, relheight = 0.1)

############################################### input_frame ###############################################
#input_frame grid
input_frame.columnconfigure((0,1,2), weight = 1, uniform = ‘a’)
input_frame.rowconfigure((0,1), weight = 1, uniform = ‘a’)
#input_frame widgets
title = ttk.Label(master = input_frame, text=‘PMICs and SBC OTP BURNING TOOL’,font = (‘timesnewroman’, 10))
device_list = ttk.Combobox(master = input_frame, values = OTP_devices, state = ‘readonly’) #device drop down list
connect_button = Button(master = input_frame, text=‘Disconnected’, background=‘#dce3df’,command = connect_button) #connect button
otp_file = tk.Label(master = input_frame, width=12, height=1) #otp file url
otp_file.config(state=‘disabled’)
load_button = Button(master = input_frame, text=‘Load’,background=‘#dce3df’,command = load_button) #otp file open button
#input_frame layout
title.grid(row = 0, column = 0, columnspan = 3,padx = 1,pady = 1)
device_list.grid(row = 1, column = 0, sticky = ‘wsne’, columnspan = 2,padx = 1,pady = 1)
connect_button.grid(row = 1, column = 2,sticky = ‘wsne’,padx = 1,pady = 1)
otp_file.grid(row = 2, column = 0, sticky = ‘wsne’, columnspan = 2,padx = 1,pady = 1)
load_button.grid(row = 2, column = 2,sticky = ‘wsne’,padx = 1,pady = 1)

############################################### operate_frame ###############################################
#operate_frame grid
operate_frame.columnconfigure((0,1), weight = 1, uniform = ‘a’)
#operate_frame widgets
burn_button = Button(master = operate_frame, text=‘Burn’,background=‘#dce3df’,state = ‘disabled’,command = burn_button_func_threading) #burn button
validate_button = Button(master = operate_frame, text=‘Validate’,background=‘#dce3df’, state = ‘disabled’,command = validate_button_func_threading) #validate button
#operate_frame layout
burn_button.grid(row = 0, column = 0, sticky = ‘wsne’,padx = 1,pady = 1)
validate_button.grid(row = 0, column = 1,sticky = ‘wsne’,padx = 1,pady = 1)

############################################### recording_frame ###############################################
#recording_frame widgets
log = ScrolledText(master = recording_frame) #width=20, height=7 #log panel, textvariable = log_string, font
log.config(font=(“Times”, 10))
log.pack(side = ‘left’, expand = True,padx = 2,pady = 4)

############################################### result_frame ###############################################
#result_frame grid
result_frame.columnconfigure((0,1,2,3), weight = 1, uniform = ‘a’)
#result_frame widgets
result = tk.Label(master = result_frame, text=‘UNKNOW’, bg = ‘yellow’, font = (‘Arial’, 12, ‘bold’)) #test result pass or fail
clear_log_button = Button(master = result_frame, text=‘clear’,background=‘#dce3df’, command = clear_log_button) #save log button
save_log_button = Button(master = result_frame, text=‘save’,background=‘#dce3df’, command = save_log_button) #save log button
#result_frame layout
result.grid(row = 0, column = 0, sticky = ‘wsne’,columnspan = 2,padx = 1,pady = 1)
clear_log_button.grid(row = 0, column = 2,sticky = ‘wsne’,padx = 1,pady = 1)
save_log_button.grid(row = 0, column = 3,sticky = ‘wsne’,padx = 1,pady = 1)

#run
window.mainloop()