Welcome to 75 TERM APP
USES:
- As a serial terminal
- Programming tool for 75F smart device like Smartnode, CM4, ITM
Developed by
Ravikirana B
"# 75f_term"
"# 75F-TERM"
| from term.term_app import term_app | |
| if __name__ == '__main__': | |
| term_app().mainloop() |
Welcome to 75 TERM APP
USES:
Developed by
Ravikirana B
"# 75f_term"
"# 75F-TERM"
| import setuptools | |
| import term | |
| try: | |
| setuptools.setup( | |
| name='term', | |
| version=term.version, | |
| description='Serial tool', | |
| url='http://rvkiran.epizy.com/tool/75F_TERM_v0.998.zip', | |
| packages=['term'], | |
| entry_points={ | |
| 'console_scripts': ['my-script=term.term_app:entry_point'], | |
| }, | |
| ) | |
| except Exception as e: | |
| print(e) |
| from tkinter import * | |
| from tkinter import ttk | |
| from tkinter import filedialog | |
| import time, os, datetime | |
| from subprocess import Popen,PIPE | |
| import serial, threading | |
| from escpos.connections import getUSBPrinter | |
| import configparser | |
| import serial.tools.list_ports as comports | |
| from tkinter import messagebox | |
| #Application start | |
| class term_app(Tk): | |
| def __init__(self): | |
| Tk.__init__(self) | |
| self.snbat_dir, self.cm4bat_dir, self.itmbat_dir = '', '', '' | |
| self.protocol('WM_DELETE_WINDOW', self.term_app_close) | |
| self.logging = False | |
| self.ser_open = False | |
| self.config_init() | |
| self.log_init() | |
| self.widget() | |
| return | |
| #Logging initialisation | |
| def log_init(self): | |
| self.batlog_file = None | |
| #Defining window size | |
| def window_size(self): | |
| sw = self.winfo_screenwidth() | |
| sh = self.winfo_screenheight() | |
| self.ww = int(sw/2) | |
| self.wh = int(sh/1.2) | |
| self.wx = sw - self.ww-150 | |
| self.wy = 5 | |
| self.swx = self.wx+20 | |
| self.swy = self.wy+50 | |
| #Do nothing function for not functioned menus and button | |
| def donothing(self): | |
| print('do nothing') | |
| def print(self): | |
| '''printers=win32print.ge | |
| print_window=Toplevel(self) | |
| print_window.geometry('300x250+%s+%s' % (self.swx, self.swy)) | |
| Label(print_window,text='Select printer').grid(row=1,column=1) | |
| printer_sel=ttk.Combobox(print_window,values=printers) | |
| printer_sel.grid(row=1,column=2)''' | |
| #MAIN window widgets | |
| def widget(self): | |
| self.window_size() | |
| self.title('75F TERM(RAVI)') | |
| self.geometry('%sx%s+%s+%s' % (self.ww, self.wh, self.wx, self.wy)) | |
| self.resizable(True, True) | |
| self.lift() | |
| self.menubar = Menu(self) | |
| # File menu options | |
| filemenu = Menu(self.menubar, tearoff=0) | |
| filemenu.add_command(label='New', command=lambda :term_app().mainloop()) | |
| '''filemenu.add_command(label='Open', command=self.donothing)''' | |
| # Adding logmenu to file menu and in logmenu creating submenu start and stop | |
| logmenu = Menu(filemenu, tearoff=0) | |
| filemenu.add_cascade(label='Log', menu=logmenu) | |
| logmenu.add_command(label='Start Log', command=self.start_log) | |
| logmenu.add_command(label="Stop log", command=self.stop_log) | |
| '''filemenu.add_command(label='Save as', command=self.donothing)''' | |
| filemenu.add_command(label='Disconnect', command=lambda :[self.ser_close(),self.title('75F TERM(RAVI) [disconnected]')]) | |
| '''printmenu = Menu(filemenu , tearoff=0) | |
| # creating submenu for print menu | |
| filemenu.add_cascade(label='Print', menu=printmenu) | |
| printmenu.add_command(label='Print', command=self.print) | |
| printmenu.add_command(label='Print preview', command=self.donothing)''' | |
| filemenu.add_command(label='Quit', command=self.quit) | |
| self.menubar.add_cascade(label='File', menu=filemenu) | |
| # Edit menu options | |
| editmenu = Menu(self.menubar, tearoff=0) | |
| editmenu.add_command(label='Cut', command=lambda :self.ser_text_box.event_generate('<<Cut>>')) | |
| editmenu.add_command(label='Copy', command=lambda :self.ser_text_box.event_generate('<<Copy>>')) | |
| editmenu.add_command(label='Paste', command=lambda :self.ser_text_box.event_generate('<<Paste>>')) | |
| self.menubar.add_cascade(label='Edit', menu=editmenu) | |
| # Setup menu options | |
| self.menubar.add_command(label='Serial Port', command=self.serial_port) | |
| # Program Menu | |
| self.programmenu = Menu(self.menubar, tearoff=0) | |
| self.programmenu.add_command(label='Program', command=self.program_GUI) | |
| self.programmenu.add_command(label='select flashtool directory', command=self.flashtool_dir) | |
| self.menubar.add_cascade(label='Program', menu=self.programmenu) | |
| # About menu options | |
| self.menubar.add_command(label='About', command=self.about) | |
| # configering self.menubar as mainmenu | |
| self.config(menu=self.menubar) | |
| # Textbox to print TX RX data | |
| vscrollbar = Scrollbar(self) | |
| self.ser_text_box = Text(self, width=200, height=40, yscrollcommand=vscrollbar.set, wrap='word',state=DISABLED) | |
| vscrollbar.pack(side=RIGHT, fill=BOTH) | |
| self.ser_text_box.pack(side=RIGHT, fill=Y) | |
| vscrollbar.config(command=self.ser_text_box.yview) | |
| # Displaying about tool in about menu | |
| def about(self): | |
| messagebox.askokcancel('About', ''' | |
| 1. This is serial tereminal tool support for all serial devices | |
| 2. It is having programming feature for only 75F smart devices | |
| Devices: Smartnode, CM4 and ITM | |
| Developed by: | |
| RAVIKIRANA B, | |
| Testing Engineer,75F India''') | |
| # Opening serial port configeration window | |
| def serial_port(self): | |
| self.menubar.entryconfig('Serial Port', state='disabled') | |
| self.serial_port_window = Toplevel(self) | |
| self.serial_port_window.title('serial port configeration') | |
| self.serial_port_window.geometry('250x250+%s+%s' % (self.swx, self.swy)) | |
| self.serial_port_window.resizable(False, False) | |
| self.serial_port_window.lift(self) | |
| self.serial_port_window.config(bg='darkorange') | |
| #Checking binding X to enable 'Serial port' | |
| self.serial_port_window.protocol("WM_DELETE_WINDOW", | |
| lambda :[self.menubar.entryconfig('Serial Port', state='normal'),self.serial_port_window.destroy()]) | |
| # com port selection | |
| com_port_label = Label(self.serial_port_window, text='COM port', bg='darkorange') | |
| com_port_label.place(x=10, y=5) | |
| self.com_ports_available = comports.comports() | |
| self.comport_select = ttk.Combobox(self.serial_port_window, values=self.com_ports_available, | |
| width=10) | |
| if self.com_ports_available: | |
| self.comport_select.current(0) | |
| self.comport_select.place(x=80, y=5) | |
| # Baudrate selection | |
| baudrate_label = Label(self.serial_port_window, text='Baudrate', bg='darkorange') | |
| baudrate_label.place(x=10, y=35) | |
| self.baudrate_select = ttk.Combobox(self.serial_port_window, values=serial.Serial.BAUDRATES, | |
| width=10) | |
| self.baudrate_select.current(16) | |
| self.baudrate_select.place(x=80, y=35) | |
| # selecting data size | |
| datasize_label = Label(self.serial_port_window, text='Data size', bg='darkorange') | |
| datasize_label.place(x=10, y=65) | |
| self.datasize_select = ttk.Combobox(self.serial_port_window, values=serial.Serial.BYTESIZES, | |
| width=10) | |
| self.datasize_select.current(3) | |
| self.datasize_select.place(x=80, y=65) | |
| # parity selection | |
| parity_label = Label(self.serial_port_window, text='Parity', bg='darkorange') | |
| parity_label.place(x=10, y=95) | |
| self.parity_select = ttk.Combobox(self.serial_port_window, values=serial.Serial.PARITIES, width=10) | |
| self.parity_select.current(0) | |
| self.parity_select.place(x=80, y=95) | |
| # Handshake selection | |
| flow_control_label = Label(self.serial_port_window, text='Flow control', bg='darkorange') | |
| flow_control_label.place(x=10, y=125) | |
| std_flow_control = 'OFF', 'RTS/CTS', 'Xon/Xoff' | |
| self.flow_control_select = ttk.Combobox(self.serial_port_window, values=std_flow_control, | |
| width=10) | |
| self.flow_control_select.current(0) | |
| self.flow_control_select.place(x=80, y=125) | |
| # Stopbit selection | |
| stopbits_label = Label(self.serial_port_window, text='Stop bit', bg='darkorange') | |
| stopbits_label.place(x=10, y=155) | |
| self.stobit_select = ttk.Combobox(self.serial_port_window, values=serial.Serial.STOPBITS, width=10) | |
| self.stobit_select.current(0) | |
| self.stobit_select.place(x=80, y=155) | |
| # OK button to setup COM port | |
| open_port_button = Button(self.serial_port_window, text='OK', command=lambda :[self.open_port(),self.serial_port_window.destroy()], bg='olive') | |
| open_port_button.place(x=30, y=185) | |
| open_port_button = Button(self.serial_port_window, text='CANCEL', bg='olive', command=lambda :[self.menubar.entryconfig('Serial Port', state='normal'),self.serial_port_window.destroy()]) | |
| open_port_button.place(x=75, y=185) | |
| return | |
| # Opening port | |
| def open_port(self): | |
| try: | |
| self.menubar.entryconfig('Serial Port', state='normal') | |
| # Opening selected port | |
| if self.com_ports_available: | |
| com_port_selected = self.comport_select.get() | |
| com_port = com_port_selected[0:4] | |
| print(com_port) | |
| # Opening selected port | |
| self.ser = serial.Serial(com_port,timeout=0) | |
| self.ser_open = True | |
| self.title('75F TERM (RAVI) [%s]' % (com_port)) | |
| self.port_config() | |
| # To read serial data | |
| self.ser_read() | |
| # If any data entered in Text widget, that data is sending in serial port | |
| self.ser_text_box.bind('<Key>', lambda ser_textbox_event: self.ser_write(ser_textbox_event)) | |
| self.serial_port_window.destroy() | |
| else: | |
| messagebox.showinfo('COM port error', 'COM port is not available') | |
| # Handling serial liabrary errors | |
| except serial.SerialException: | |
| try: | |
| if self.ser.isOpen(): | |
| self.ser.close() | |
| self.open_port() | |
| except Exception: | |
| messagebox.showinfo('COM port error', 'cannot open %s.Access is denied' % (com_port)) | |
| self.title('75F TERM(RAVI) [disconnected]') | |
| # Closing serial port if opened | |
| def ser_close(self): | |
| if self.ser_open is True: | |
| self.ser.close() | |
| self.ser_open = False | |
| else: | |
| messagebox.showinfo('Port error', 'Port not opened') | |
| # writing data to serial if any data entered in input textbox | |
| def ser_write(self, ser_textbox_event): | |
| datatosend = ser_textbox_event.char | |
| if self.ser.isOpen(): | |
| self.ser.write(datatosend.encode('utf-8','ignore')) | |
| return | |
| # Serial port read | |
| def ser_read(self): | |
| if self.ser_open is True: | |
| while self.ser.inWaiting(): | |
| received_data = self.ser.readline().decode('utf-8','ignore') | |
| data=re.sub(r'[^\w\s\d\n _=.:?/!*<>-?]','-',received_data,re.UNICODE) | |
| self.ser_text_box.config(state=NORMAL) | |
| self.ser_text_box.insert(END, data) | |
| self.ser_text_box.config(state=DISABLED) | |
| if self.logging is True: | |
| self.log(data) | |
| self.ser_text_box.yview_pickplace('end') | |
| if self.ser.isOpen(): | |
| self.after(100, self.ser_read) | |
| return | |
| # Configering serial port parameters | |
| def port_config(self): | |
| if self.ser.isOpen(): | |
| # Baudrate selection | |
| self.ser.baudrate = self.baudrate_select.get() | |
| # Datasize selection | |
| self.ser.bytesize = int(self.datasize_select.get()) | |
| # Parity selection | |
| self.ser.parity = self.parity_select.get() | |
| # Stopbits selection | |
| self.ser.stopbits = int(self.stobit_select.get()) | |
| print(self.ser.get_settings()) | |
| return | |
| # Logging serial data into text file with date & time | |
| # logging file default name format is "log_date_time.txt" | |
| def start_log(self): | |
| if self.logging is False: | |
| log_filename = 'log_' + time.strftime('%Y%m%d_%H%M%S') + '.txt' | |
| self.logdir = filedialog.asksaveasfilename(initialfile=log_filename, title='select file', | |
| filetypes=(('.txt file', '*.txt'), ('all files', '*.*'))) | |
| if self.logdir: | |
| self.logging = True | |
| else: | |
| messagebox.showinfo('Logging info', 'Already logging') | |
| return | |
| # Stop logging if logging started and closing logging file | |
| def log(self,data): | |
| log_file=open(self.logdir,'a+') | |
| timestamp=str(time.strftime("[%m/%d/%Y %H:%M:%S]\t",time.localtime())) | |
| log_file.write('%s: %s\t'%(timestamp,data)) | |
| #print('%s: %s\t'%(timestamp,data)) | |
| log_file.close() | |
| def stop_log(self): | |
| if self.logging: | |
| self.logging = False | |
| self.logfile.close() | |
| else: | |
| messagebox.showinfo('Log error', 'Logging not started') | |
| return | |
| # Capturing FLASHTOOL directory and creating file "config_files" | |
| def flashtool_dir(self): | |
| tool_dir = filedialog.askdirectory() | |
| if tool_dir: | |
| self.config_ini.set('FLASHTOOL INFORMATION', 'FLASTOOL DIR', tool_dir) | |
| self.configini = open('./config_files/configeration.ini', 'w') | |
| self.config_ini.write(self.configini) | |
| self.configini.close() | |
| print('tool director is selected') | |
| if 'config_files' in os.listdir(tool_dir): | |
| None | |
| #print(os.listdir(tool_dir)) | |
| else: | |
| os.mkdir(tool_dir + '/config_files') | |
| return | |
| # Setting up intial programming configeration | |
| def config_init(self): | |
| self.config_ini = configparser.ConfigParser() | |
| self.config_ini.read('./config_files/configeration.ini') | |
| if 'config_files' in os.listdir('.'): | |
| if 'configeration.ini' in os.listdir('./config_files/'): | |
| if self.config_ini.has_section('FLASHTOOL INFORMATION'): | |
| None | |
| else: | |
| self.config_ini.add_section('FLASHTOOL INFORMATION') | |
| self.config_ini.set('FLASHTOOL INFORMATION', 'FLASTOOL DIR', '') | |
| if self.config_ini.has_section('APP DETAILS'): | |
| None | |
| else: | |
| # Adding all configeration in .ini file | |
| self.config_ini.add_section('APP DETAILS') | |
| self.config_ini.set('APP DETAILS', 'TOOL SN', '') | |
| self.config_ini.set('APP DETAILS', 'Device name', '') | |
| self.config_ini.set('APP DETAILS', 'application file', '') | |
| self.config_ini.set('APP DETAILS', 'Backup file', '') | |
| self.config_ini.set('APP DETAILS', 'Backup ver', '') | |
| self.config_ini.set('APP DETAILS', 'Bootloader file', '') | |
| self.config_ini.set('APP DETAILS', 'application ver', '') | |
| self.config_ini.set('APP DETAILS', 'Bootloader ver', '') | |
| self.config_ini.set('APP DETAILS', 'Bootloader', '') | |
| configini = open('./config_files/configeration.ini', 'w') | |
| self.config_ini.write(configini) | |
| configini.close() | |
| else: | |
| configini = open('./config_files/configeration.ini', 'w') | |
| self.config_ini.write(configini) | |
| configini.close() | |
| self.config_init() | |
| else: | |
| os.mkdir('./config_files') | |
| self.config_init() | |
| # Creating programming window and it' elements | |
| def program_GUI(self): | |
| #Disbling program menu option to avoid multi program window | |
| self.programmenu.entryconfig('Program', state='disabled') | |
| #opening programming window | |
| self.program_window=Toplevel(self) | |
| self.program_window.title('Programming...') | |
| self.program_window.geometry('500x400+%s+%s' % (self.swx, self.swy)) | |
| self.program_window.resizable(False, False) | |
| self.program_window.lift(self) | |
| self.program_window.config(bg='orange') | |
| #Checking binding X to enable Program menu option | |
| self.program_window.protocol("WM_DELETE_WINDOW", lambda :[self.programmenu.entryconfig('Program', state='normal'),self.program_window.destroy()]) | |
| self.program_window_widget() | |
| def program_window_widget(self): | |
| # Reading configeration file | |
| self.config_ini.read('./config_files/configeration.ini') | |
| #variable declaration for Entry or Text entry | |
| self.app_ver, self.backup_ver, self.bootloader_ver=StringVar(), StringVar(), StringVar() | |
| #Programming tool information | |
| Label(self.program_window,text='TOOL',font='arial 10',bg='orange').place(x=20,y=10) | |
| self.tool=Text(self.program_window,height=1,width=15) | |
| self.tool.insert(0.0,self.config_ini.get('APP DETAILS', 'TOOL SN')) | |
| self.tool.place(x=140,y=10) | |
| #Select devices | |
| Label(self.program_window, text='Select devices', font='arial 10', bg='orange').place(x=20, y=40) | |
| devices = 'smartnode', 'cm4', 'itm' | |
| self.selected_device=ttk.Combobox(self.program_window,width=17,values=devices) | |
| self.selected_device.set(self.config_ini.get('APP DETAILS', 'Device name')) | |
| if self.selected_device.get() == '': | |
| self.selected_device.current(0) | |
| self.selected_device.place(x=140,y=40) | |
| #App ver. | |
| Label(self.program_window, text='App ver.', font='arial 10', bg='orange').place(x=20, y=70) | |
| app_ver=Entry(self.program_window,width=20,textvariable=self.app_ver) | |
| app_ver.insert(END,self.config_ini.get('APP DETAILS', 'application ver')) | |
| app_ver.place(x=140,y=70) | |
| #App hex file | |
| Label(self.program_window, text='App hex file', font='arial 10', bg='orange').place(x=20, y=100) | |
| app_hexfile=Text(self.program_window,width=30,height=1) | |
| app_hexfile.insert(0.0,self.config_ini.get('APP DETAILS', 'application file')) | |
| app_hexfile.place(x=140,y=100) | |
| Button(self.program_window,text='/',bg='darkorange',width=3,command=lambda :self.askfile('application file', '*.hex' )).place(x=390,y=100) | |
| #Backup ver. | |
| Label(self.program_window, text='Backup ver.', font='arial 10', bg='orange').place(x=20, y=130) | |
| backup_ver = Entry(self.program_window, width=20,textvariable=self.backup_ver) | |
| backup_ver.insert(END, self.config_ini.get('APP DETAILS', 'Backup ver')) | |
| backup_ver.place(x=140, y=130) | |
| #Checking Backup needed or not | |
| self.backupvarvar = BooleanVar() | |
| Checkbutton(self.program_window, variable=self.backupvarvar, bg='orange').place(x=250, y=130) | |
| #Backup hex file | |
| Label(self.program_window, text='Backup hex file', font='arial 10', bg='orange').place(x=20, y=170) | |
| backup_hexfile = Text(self.program_window, width=30,height=1) | |
| backup_hexfile.insert(0.0,self.config_ini.get('APP DETAILS', 'Backup file')) | |
| backup_hexfile.place(x=140, y=170) | |
| Button(self.program_window, text='/', width=3, bg='darkorange',command=lambda :self.askfile('backup file','*.hex')).place(x=390, y=170) | |
| #Bootloader ver. | |
| Label(self.program_window, text='Bootloader ver.', font='arial 10', bg='orange').place(x=20, y=200) | |
| bootloader_ver = Entry(self.program_window, width=20,textvariable=self.bootloader_ver) | |
| bootloader_ver.insert(END,self.config_ini.get('APP DETAILS', 'Bootloader ver')) | |
| bootloader_ver.place(x=140, y=200) | |
| #Checking bootloader needed or not | |
| self.bootloadervar=StringVar(value=self.config_ini.get('APP DETAILS', 'Bootloader')) | |
| Checkbutton(self.program_window,variable=self.bootloadervar,onvalue='True',offvalue='False',bg='orange').place(x=250,y=200) | |
| #Bootloader hex file | |
| Label(self.program_window, text='Bootloader hex file', font='arial 10', bg='orange').place(x=20, y=230) | |
| bootloader_hexfile = Text(self.program_window, width=30, height=1) | |
| bootloader_hexfile.insert(0.0,self.config_ini.get('APP DETAILS', 'Bootloader file')) | |
| bootloader_hexfile.place(x=140, y=230) | |
| Button(self.program_window, text='/', width=3, bg='darkorange',command=lambda :self.askfile('bootloader file','*.hex')).place(x=390, y=230) | |
| #Program button | |
| self.program_button=Button(self.program_window, text='PROGRAM', font='arial 10', bg='darkorange',command=self.program) | |
| self.program_button.place(x=150, y=270) | |
| #Programming status Textbox | |
| self.pgm_status_out=Text(self.program_window, font='arial 10',height=4,width=63,wrap=WORD) | |
| self.pgm_status_out.place(x=20, y=310) | |
| vscrollbar = Scrollbar(self.program_window,command=self.pgm_status_out.yview) | |
| vscrollbar.place(x=465,y=310,height=68) | |
| self.pgm_status_out['yscrollcommand']=vscrollbar.set | |
| self.program_config() | |
| self.program_window.mainloop() | |
| def program(self): | |
| self.pgm_thread=threading.Thread(target=self.start_program) | |
| self.pgm_thread.start() | |
| self.flash_error = False | |
| self.program_button.config(state=DISABLED,text='programming...') | |
| self.pgm_status_out.config(fg='green') | |
| self.pgm_status_out.delete(0.0,END) | |
| self.boot=True | |
| self.pgm_killed=False | |
| def program_config(self): | |
| try: | |
| thread = threading.Timer(1, self.program_config) | |
| # Saving all data into configeration file "configeration.ini" | |
| self.config_ini.set('APP DETAILS', 'TOOL SN', self.tool.get(0.0, END)) | |
| self.config_ini.set('APP DETAILS', 'Device name', self.selected_device.get()) | |
| self.config_ini.set('APP DETAILS', 'application ver', self.app_ver.get()) | |
| self.config_ini.set('APP DETAILS', 'Bootloader ver', self.bootloader_ver.get()) | |
| self.config_ini.set('APP DETAILS', 'Backup ver', self.backup_ver.get()) | |
| self.config_ini.set('APP DETAILS', 'Bootloader', str(self.bootloadervar.get())) | |
| configini = open('./config_files/configeration.ini', 'w+') | |
| self.config_ini.write(configini) | |
| configini.close() | |
| self.program_window.update() | |
| thread.start() | |
| except Exception: | |
| thread.cancel() | |
| #Capturing hex filenames | |
| def askfile(self, name ,type): | |
| file=filedialog.askopenfilename(filetypes=(('%s files'%type,type),)) | |
| if file: | |
| self.config_ini.set('APP DETAILS',name,file) | |
| self.configini = open('./config_files/configeration.ini', 'w') | |
| self.config_ini.write(self.configini) | |
| self.configini.close() | |
| self.program_window.lift(self) | |
| self.program_window_widget() | |
| # Opening command prompt in flashtool directory and sending flashing commands | |
| def start_program(self): | |
| try: | |
| print('programming') | |
| device=self.selected_device.get() | |
| tool_dir = self.config_ini.get('FLASHTOOL INFORMATION', 'FLASTOOL DIR') | |
| self.set_ini = configparser.ConfigParser() | |
| ini_readpath = tool_dir + '/%s.ini' % device | |
| self.set_ini.read(ini_readpath) | |
| self.set_ini.set('ToolInfo', 'Serial', self.config_ini.get('APP DETAILS', 'TOOL SN')) | |
| self.set_ini.set('FirmwareInfo', 'BootloaderFirmwareVersion',self.bootloader_ver.get()) | |
| self.set_ini.set('FirmwareInfo', 'Bootloader', self.config_ini.get('APP DETAILS', 'bootloader file')) | |
| cmd1 = 'flashtool.exe -f "' + tool_dir + '/config_files/%s.ini" -c flashmanufacture' % device | |
| cmd2= 'flashtool.exe -c flashapp -f ' + tool_dir + '/config_files/%s.ini' % device | |
| # Checking backup flash ver. is enetered or not | |
| # If back up ver. is there then flashing backup ver. and erasing flashing | |
| if self.backupvarvar.get(): | |
| print('entered into backup version') | |
| # Flashing backup ver. | |
| self.pgm_status_out.insert(END,'Started flashing app ver...\n') | |
| self.set_ini.set('FirmwareInfo', 'ApplicationFirmwareVersion', self.backup_ver.get()) | |
| self.set_ini.set('FirmwareInfo', 'ApplicationImage', self.config_ini.get('APP DETAILS', 'Backup file')) | |
| open_ini = open(tool_dir + '/config_files/%s.ini' % device, 'w') | |
| self.set_ini.write(open_ini) | |
| open_ini.close() | |
| if self.bootloadervar.get() == 'True': | |
| cmd = cmd1 | |
| progress_time =170 | |
| else: | |
| cmd = cmd2 | |
| progress_time = 100 | |
| print(cmd) | |
| self.pgmcmd = Popen('cmd /c' + cmd, cwd=tool_dir,stdout=PIPE) | |
| self.command_prompt('Backup ver. flashing done\n',progress_time) | |
| time.sleep(2) | |
| self.boot=False | |
| # Erasing backup ver. | |
| if self.pgm_killed is False: | |
| self.pgm_status_out.insert(END,'Started erasing...\n') | |
| cmd3 = 'flashtool.exe -c erasebackup -f ' + tool_dir + '/config_files/%s.ini' % device | |
| self.pgmcmd =Popen('cmd /c' + cmd3, cwd=tool_dir, stdout=PIPE) | |
| self.command_prompt('Erasing done.\n',15) | |
| time.sleep(13) | |
| # Flashing application ver | |
| if self.pgm_killed is False: | |
| self.pgm_status_out.insert(END,'Flashing application ver...\n') | |
| self.set_ini.set('FirmwareInfo', 'ApplicationFirmwareVersion', | |
| self.config_ini.get('APP DETAILS', 'application ver')) | |
| self.set_ini.set('FirmwareInfo', 'ApplicationImage', self.config_ini.get('APP DETAILS', 'application file')) | |
| open_ini = open(tool_dir + '/config_files/%s.ini' % device, 'w') | |
| self.set_ini.write(open_ini) | |
| open_ini.close() | |
| if (self.bootloadervar.get() == 'True' ) and (self.bootloadervar.get()): | |
| cmd=cmd1 | |
| progress_time = 170 | |
| else: | |
| cmd=cmd2 | |
| progress_time = 100 | |
| print(cmd) | |
| self.pgmcmd = Popen('cmd /c' + cmd, cwd=tool_dir, stdout=PIPE,shell=True) | |
| self.command_prompt('Flashing app ver done.\n',progress_time) | |
| self.program_button.config(text='PROGRAM', state=NORMAL) | |
| except Exception as e: | |
| if re.search(r'No section',str(e),re.I): | |
| messagebox.showinfo('Info','Please select FLASHTOOL directory') | |
| self.program_window.lift() | |
| self.program_button.config(text='PROGRAM', state=NORMAL) | |
| else: | |
| print(e) | |
| return | |
| def command_prompt(self,status,maxvalue): | |
| #self.pgmcmd.poll() | |
| self.progress=ttk.Progressbar(self.program_window,orient='horizontal',maximum=maxvalue,length=200) | |
| self.progress.place(x=260,y=275) | |
| self.progress.start(interval=1000) | |
| # Reading command prompt output and displaying the errors | |
| while self.pgmcmd.poll() is None: | |
| out=self.pgmcmd.stdout.readline() | |
| self.pgmcmd.stdout.flush() | |
| print(str(out)) | |
| errors=['No device detected','Could not find tool','No Firmware Version Embedded In Image','Failed to Locate',\ | |
| 'Unexpected Chip Identifier','Could not establish connection to device','Invalid Config Item ',\ | |
| 'Unrecognized or ambiguous command','Firmware Version Mismatch','Could not write ARM memory','ERROR'] | |
| error_dict={'No device detected':'Pls check connection!!','Could not find tool':'Pls check programmer connected or not and serial number of programmer!!',\ | |
| 'No Firmware Version Embedded In Image':'Pls select proper hex files!!','Failed to Locate':'Check hex files inserted or not!!',\ | |
| 'Unexpected Chip Identifier':'Pls select proper hex files!!','Could not establish connection to device':'Please check connection!!','Invalid Config Item ':'Check FW version!!',\ | |
| 'Unrecognized or ambiguous command':'check programmer serial number!!','Firmware Version Mismatch':'Insert proper version hex file!!','Could not write ARM memory':'!!','ERROR':'!!'} | |
| for error in errors: | |
| error_search = re.search(error, str(out), re.I) | |
| if error_search: | |
| self.pgm_status_out.config(fg='HotPink') | |
| self.pgm_status_out.insert(END,'Error: '+error_search.group()+' -? '+error_dict[error_search.group()]+'\n') | |
| self.pgm_status_out.yview_pickplace('end') | |
| self.flash_error=True | |
| if self.flash_error: | |
| self.progress.destroy() | |
| self.program_button.config(text='PROGRAM', state=NORMAL) | |
| self.pgmcmd.kill() | |
| self.pgm_killed=True | |
| return | |
| self.pgm_thread.join() | |
| time.sleep(2) | |
| self.progress.destroy() | |
| if self.flash_error is False: | |
| self.pgm_status_out.insert(END,status+'\n') | |
| return | |
| def term_app_close(self): | |
| self.destroy() |
75F-TERM first upload