diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/configuration/Appconfig.py | 16 | ||||
-rw-r--r-- | src/frontEnd/Application.py | 170 | ||||
-rwxr-xr-x | src/maker/Appconfig.py | 37 | ||||
-rwxr-xr-x | src/maker/ModelGeneration.py | 2 | ||||
-rw-r--r-- | src/maker/createkicad.py | 175 | ||||
-rw-r--r-- | src/projManagement/Kicad.py | 16 | ||||
-rw-r--r-- | src/projManagement/newProject.py | 3 |
7 files changed, 139 insertions, 280 deletions
diff --git a/src/configuration/Appconfig.py b/src/configuration/Appconfig.py index 00977ca0..4decf0b6 100644 --- a/src/configuration/Appconfig.py +++ b/src/configuration/Appconfig.py @@ -13,7 +13,7 @@ # MODIFIED: Rahul Paknikar, rahulp@iitb.ac.in # ORGANIZATION: eSim Team at FOSSEE, IIT Bombay # CREATED: Tuesday 24 February 2015 -# REVISION: Tuesday 13 September 2022 +# REVISION: Thursday 29 June 2023 # ========================================================================= from PyQt5 import QtWidgets @@ -80,20 +80,6 @@ class Appconfig(QtWidgets.QWidget): print("Cannot access Modelica map file --- .esim folder") print(str(e)) - # Open file and read KiCad config path - try: - init_path = '../../' - if os.name == 'nt': - init_path = '' - - file = open(init_path + - 'library/supportFiles/kicad_config_path.txt', 'r') - kicad_path = file.read().rstrip() - file.close() - except BaseException as e: - kicad_path = None - print(str(e)) - try: project_explorer = json.load(open(dictPath["path"])) except BaseException: diff --git a/src/frontEnd/Application.py b/src/frontEnd/Application.py index 96be7ca4..a6f2cd10 100644 --- a/src/frontEnd/Application.py +++ b/src/frontEnd/Application.py @@ -20,7 +20,6 @@ import os import sys -import shutil import traceback if os.name == 'nt': @@ -56,9 +55,6 @@ class Application(QtWidgets.QMainWindow): # Calling __init__ of super class QtWidgets.QMainWindow.__init__(self, *args) - # Flag for mode of operation. Default is set to offline mode. - self.online_flag = False - # Set slot for simulation end signal to plot simulation data self.simulationEndSignal.connect(self.plotSimulationData) @@ -126,28 +122,6 @@ class Application(QtWidgets.QMainWindow): self.wrkspce.setShortcut('Ctrl+W') self.wrkspce.triggered.connect(self.change_workspace) - self.switchmode = None - self.validate_mode() - if self.online_flag is True: - self.switchmode = QtWidgets.QAction(QtGui.QIcon( - init_path + 'images/online.png'), - '<b>Go Offline</b>', self - ) - elif self.online_flag is False: - self.switchmode = QtWidgets.QAction(QtGui.QIcon( - init_path + 'images/offline.png'), - '<b>Go Online</b>', self - ) - elif self.online_flag is None: - self.switchmode = QtWidgets.QAction(QtGui.QIcon( - init_path + 'images/disable.png'), - '<b>Mode switching has been disabled. ' + - 'Default mode set to offline</b>', self - ) - self.switchmode.setEnabled(False) - self.switchmode.setShortcut('Ctrl+G') - self.switchmode.triggered.connect(self.change_mode) - self.helpfile = QtWidgets.QAction( QtGui.QIcon(init_path + 'images/helpProject.png'), '<b>Help</b>', self @@ -160,7 +134,6 @@ class Application(QtWidgets.QMainWindow): self.topToolbar.addAction(self.openproj) self.topToolbar.addAction(self.closeproj) self.topToolbar.addAction(self.wrkspce) - self.topToolbar.addAction(self.switchmode) self.topToolbar.addAction(self.helpfile) # ## This part is meant for SoC Generation which is currently ## @@ -398,149 +371,6 @@ class Application(QtWidgets.QMainWindow): self.hide() self.obj_workspace.show() - def validate_mode(self): - """ - This functions checks whether proper fp-lib-table* files are \ - available or not. If not, then move appropriate files from \ - library/supportFiles folder and set `self.online_flag` accordingly. - - @params - - @return - None - """ - remove = False - - if self.obj_appconfig.kicad_path is not None: - - if not os.path.exists( - self.obj_appconfig.kicad_path + "/fp-lib-table" - ): - remove = True - elif os.path.exists(self.obj_appconfig.kicad_path + - "/fp-lib-table-offline"): - if os.path.exists(self.obj_appconfig.kicad_path + - "/fp-lib-table-online"): - remove = True - os.remove(self.obj_appconfig.kicad_path + - "/fp-lib-table") - else: - self.online_flag = True - else: - if not os.path.exists(self.obj_appconfig.kicad_path + - "/fp-lib-table-online"): - remove = True - os.remove(self.obj_appconfig.kicad_path + - "/fp-lib-table") - else: - self.online_flag = False - - if remove: - # Remove invalid files - if os.path.exists( - self.obj_appconfig.kicad_path + "/fp-lib-table-offline" - ): - os.remove(self.obj_appconfig.kicad_path + - "/fp-lib-table-offline") - - if os.path.exists( - self.obj_appconfig.kicad_path + "/fp-lib-table-online" - ): - os.remove(self.obj_appconfig.kicad_path + - "/fp-lib-table-online") - - # Restore original files - shutil.copy( - init_path + 'library/supportFiles/fp-lib-table-online', - self.obj_appconfig.kicad_path + "/" - ) - shutil.copy( - init_path + 'library/supportFiles/fp-lib-table', - self.obj_appconfig.kicad_path + "/" - ) - - self.online_flag = False - else: - self.online_flag = None - - def change_mode(self): - """ - - This function is used for changing mode of operation for KiCad. \ - - There are three modes of operation : - - online - - offline - - disable - - - If none of the KiCad tools (associated with eSim) are \ - open, then validate this mode by calling the function \ - `validate_mode` and depending on online_flag, swap \ - appropriate fp-lib-table files. - - If any of the KiCad tools (associated with eSim) is open, \ - then ask user to close all these tools. - - If `online_flag` is `None`, then disable this feature. - - @params - - @return - None - """ - if not self.obj_kicad.check_open_schematic(): - self.validate_mode() - if self.online_flag is True: - os.rename( - self.obj_appconfig.kicad_path + "/fp-lib-table", - self.obj_appconfig.kicad_path + - "/fp-lib-table-online" - ) - os.rename( - self.obj_appconfig.kicad_path + - "/fp-lib-table-offline", - self.obj_appconfig.kicad_path + "/fp-lib-table" - ) - self.switchmode.setIcon( - QtGui.QIcon(init_path + 'images/offline.png') - ) - self.switchmode.setText('<b>Go Online</b>') - self.switchmode.setEnabled(True) - self.online_flag = False - - elif self.online_flag is False: - os.rename( - self.obj_appconfig.kicad_path + "/fp-lib-table", - self.obj_appconfig.kicad_path + - "/fp-lib-table-offline" - ) - os.rename( - self.obj_appconfig.kicad_path + - "/fp-lib-table-online", - self.obj_appconfig.kicad_path + "/fp-lib-table" - ) - self.switchmode.setIcon( - QtGui.QIcon(init_path + 'images/online.png') - ) - self.switchmode.setText('<b>Go Offline</b>') - self.switchmode.setEnabled(True) - self.online_flag = True - - elif self.online_flag is None: - self.switchmode.setIcon( - QtGui.QIcon(init_path + 'images/disable.png') - ) - self.switchmode.setText( - '<b>Mode switching has been ' + - 'disabled. Default mode set to offline</b>.' - ) - self.switchmode.setEnabled(False) - else: - self.msg = QtWidgets.QErrorMessage() - self.msg.setWindowTitle("Error Message") - self.msg.setModal(True) - self.msg.showMessage( - 'Please save and close all the KiCad ' + - 'windows first, then change the mode' - ) - self.msg.exec_() - def help_project(self): """ This function opens usermanual in dockarea. diff --git a/src/maker/Appconfig.py b/src/maker/Appconfig.py index 06758898..315ecff8 100755 --- a/src/maker/Appconfig.py +++ b/src/maker/Appconfig.py @@ -24,16 +24,29 @@ class Appconfig: # parser_ngveri.read(os.path.join(home, # os.path.join('.ngveri', 'config.ini'))) - kicad_lib_template = { - "start_def": "DEF comp_name U 0 40 Y Y 1 F N", - "U_field": "F0 \"U\" 2850 1800 60 H V C CNN", - "comp_name_field": "F1 \"comp_name\" 2850 2000 60 H V C CNN", - "blank_field": ["F2 blank_quotes 2850 1950 60 H V C CNN", - "F3 blank_quotes 2850 1950 60 H V C CNN"], - "start_draw": "DRAW", - "draw_pos": "S 2350 2100 3350 1800 0 1 0 N", - "input_port": "X in 1 2150 2000 200 R 50 50 1 1 I", - "output_port": "X out 2 3550 2000 200 L 50 50 1 1 O", - "end_draw": "ENDDRAW", - "end_def": "ENDDEF" + # KiCad v6 Library Template + kicad_sym_template = { + "start_def": "(symbol \"comp_name\" (pin_names (offset 1.016)) " + + "(in_bom yes) (on_board yes)", + "U_field": "(property \"Reference\" \"U\" (id 0) (at 12 15 0)" + + "(effects (font (size 1.524 1.524))))", + "comp_name_field": "(property \"Value\" \"comp_name\" (id 1) " + + "(at 12 18 0)(effects (font (size 1.524 1.524))))", + "blank_field": [ + "(property \"Footprint\" blank_quotes (id 2) " + + "(at 72.39 49.53 0)(effects (font (size 1.524 1.524))))", + "(property \"Datasheet\" blank_quotes (id 3) " + + "(at 72.39 49.53 0)(effects (font (size 1.524 1.524))))" + ], + "draw_pos": "(symbol \"comp_name\"(rectangle (start 0 0 ) " + + "(end 25.40 3.6 )(stroke (width 0) (type default) " + + "(color 0 0 0 0))(fill (type none))))", + "start_draw": "(symbol", + "input_port": "(pin input line(at -5.15 0.54 0 )(length 5.08 )" + + "(name \"in\" (effects(font(size 1.27 1.27))))" + + "(number \"1\" (effects (font (size 1.27 1.27)))))", + "output_port": "(pin output line(at 30.52 0.54 180 )(length 5.08 )" + + "(name \"out\" (effects(font(size 1.27 1.27))))" + + "(number \"2\" (effects (font (size 1.27 1.27)))))", + "end_draw": "))" } diff --git a/src/maker/ModelGeneration.py b/src/maker/ModelGeneration.py index 6ba54405..7dce1de7 100755 --- a/src/maker/ModelGeneration.py +++ b/src/maker/ModelGeneration.py @@ -216,7 +216,7 @@ class ModelGeneration(QtWidgets.QWidget): modelname = str(m.name) schematicLib = createkicad.AutoSchematic() schematicLib.init(modelname, self.modelpath) - error = schematicLib.createkicad() + error = schematicLib.createKicadSymbol() if error == "Error": return "Error" return "No Error" diff --git a/src/maker/createkicad.py b/src/maker/createkicad.py index af30cee0..0ce239a0 100644 --- a/src/maker/createkicad.py +++ b/src/maker/createkicad.py @@ -1,4 +1,4 @@ -# ========================================================================= +# ============================================================================== # FILE: createkicad.py # # USAGE: --- @@ -21,47 +21,41 @@ # Rohinth Ram, Madras Institue of Technology # Charaan S., Madras Institue of Technology # Nalinkumar S., Madras Institue of Technology +# Partha Singha Roy, Kalyani Government Engineering College # ORGANIZATION: eSim Team at FOSSEE, IIT Bombay # CREATED: Monday 29, November 2021 -# REVISION: Tuesday 25, January 2022 -# ========================================================================= +# REVISION: Friday 16, June 2023 +# ============================================================================== -# importing the files and libraries from . import Appconfig import re import os import xml.etree.cElementTree as ET from PyQt5 import QtWidgets -# beginning the AutoSchematic Class - class AutoSchematic: - - # initialising the variables here def init(self, modelname, modelpath): self.App_obj = Appconfig.Appconfig() self.modelname = modelname.split('.')[0] - self.template = self.App_obj.kicad_lib_template.copy() + self.template = self.App_obj.kicad_sym_template.copy() self.xml_loc = self.App_obj.xml_loc self.lib_loc = self.App_obj.lib_loc self.modelpath = modelpath if os.name == 'nt': eSim_src = self.App_obj.src_home inst_dir = eSim_src.replace('\\eSim', '') - self.kicad_ngveri_lib = \ - inst_dir + '/KiCad/share/kicad/library/eSim_Ngveri.lib' + self.kicad_ngveri_sym = \ + inst_dir + '/KiCad/share/kicad/symbols/eSim_Ngveri.kicad_sym' else: - self.kicad_ngveri_lib = '/usr/share/kicad/library/eSim_Ngveri.lib' + self.kicad_ngveri_sym = \ + '/usr/share/kicad/symbols/eSim_Ngveri.kicad_sym' # self.parser = self.App_obj.parser_ngveri - # creating KiCAD library using this function - def createkicad(self): - - xmlFound = None - # read_file = open(self.modelpath+'connection_info.txt', 'r') - # data = read_file.readlines() - # print(data) + def createKicadSymbol(self): + ''' + creating KiCad library using this function + ''' xmlFound = None for root, dirs, files in os.walk(self.xml_loc): if (str(self.modelname) + '.xml') in files: @@ -72,7 +66,7 @@ class AutoSchematic: if xmlFound is None: self.getPortInformation() self.createXML() - self.createLib() + self.createSym() elif (xmlFound == os.path.join(self.xml_loc, 'Ngveri')): print('Library already exists...') @@ -88,8 +82,8 @@ class AutoSchematic: print("Overwriting existing libraries") self.getPortInformation() self.createXML() - self.removeOldLibrary() # Removes the existng library - self.createLib() + self.removeOldLibrary() # Removes the existing library + self.createSym() else: print("Library Creation Cancelled") return "Error" @@ -103,16 +97,20 @@ class AutoSchematic: QtWidgets.QMessageBox.Ok ) - # getting the port information here def getPortInformation(self): + ''' + getting the port information here + ''' portInformation = PortInfo(self, self.modelpath) portInformation.getPortInfo() self.portInfo = portInformation.bit_list self.input_length = portInformation.input_len self.portName = portInformation.port_name - # creating the XML files in eSim-2.2/library/modelParamXML/Ngveri def createXML(self): + ''' + creating the XML files at `library/modelParamXML/Ngveri` + ''' cwd = os.getcwd() xmlDestination = os.path.join(self.xml_loc, 'Ngveri') self.splitText = "" @@ -145,8 +143,10 @@ class AutoSchematic: print("Leaving the directory ", xmlDestination) os.chdir(cwd) - # Calculates the maximum between input and output ports def findBlockSize(self): + ''' + Calculates the maximum between input and output ports + ''' ind = self.input_length return max( self.char_sum(self.portInfo[:ind]), @@ -156,52 +156,72 @@ class AutoSchematic: def char_sum(self, ls): return sum([int(x) for x in ls]) - # removing the old library def removeOldLibrary(self): + ''' + removing the old library + ''' cwd = os.getcwd() os.chdir(self.lib_loc) print("Changing directory to ", self.lib_loc) - f = open(self.kicad_ngveri_lib) - lines = f.readlines() - f.close() + sym_file = open(self.kicad_ngveri_sym) + lines = sym_file.readlines() + sym_file.close() output = [] line_reading_flag = False for line in lines: - if line.startswith("DEF"): - if line.split()[1] == self.modelname: + if line.startswith("(symbol"): # Eeschema Template start + if line.split()[1] == f"\"{self.modelname}\"": line_reading_flag = True if not line_reading_flag: output.append(line) - if line.startswith("ENDDEF"): + if line.startswith("))"): # Eeschema Template end line_reading_flag = False - f = open(self.kicad_ngveri_lib, 'w') + sym_file = open(self.kicad_ngveri_sym, 'w') for line in output: - f.write(line) + sym_file.write(line) os.chdir(cwd) print("Leaving directory, ", self.lib_loc) - # creating the library - def createLib(self): - self.dist_port = 100 # Distance between two ports - self.inc_size = 100 # Increment size of a block + def createSym(self): + ''' + creating the symbol + ''' + self.dist_port = 2.54 # Distance between two ports (mil) + self.inc_size = 2.54 # Increment size of a block (mil) cwd = os.getcwd() os.chdir(self.lib_loc) print("Changing directory to ", self.lib_loc) - lib_file = open(self.kicad_ngveri_lib, "a") + # Removing ")" from "eSim_Ngveri.kicad_sym" + file = open(self.kicad_ngveri_sym, "r") + content_file = file.read() + new_content_file = content_file[:-1] + file.close() + file = open(self.kicad_ngveri_sym, "w") + file.write(new_content_file) + file.close() + + # Appending new schematic block + sym_file = open(self.kicad_ngveri_sym, "a") line1 = self.template["start_def"] line1 = line1.split() line1 = [w.replace('comp_name', self.modelname) for w in line1] self.template["start_def"] = ' '.join(line1) - if os.stat(self.kicad_ngveri_lib).st_size == 0: - lib_file.write("EESchema-LIBRARY Version 2.3" + "\n\n") - # lib_file.write("#encoding utf-8"+ "\n"+ "#"+ "\n" + + + if os.stat(self.kicad_ngveri_sym).st_size == 0: + sym_file.write( + "(kicad_symbol_lib (version 20211014) " + + "(generator kicad_symbol_editor)" + + "\n\n" + ) # Eeschema starter code + + # sym_file.write("#encoding utf-8"+ "\n"+ "#"+ "\n" + # "#test_compo" + "\n"+ "#"+ "\n") - lib_file.write( + sym_file.write( self.template["start_def"] + "\n" + self.template["U_field"] + "\n" ) @@ -210,7 +230,7 @@ class AutoSchematic: line3 = [w.replace('comp_name', self.modelname) for w in line3] self.template["comp_name_field"] = ' '.join(line3) - lib_file.write(self.template["comp_name_field"] + "\n") + sym_file.write(self.template["comp_name_field"] + "\n") line4 = self.template["blank_field"] line4_1 = line4[0] @@ -223,18 +243,23 @@ class AutoSchematic: line4[1] = ' '.join(line4_2) self.template["blank_qoutes"] = line4 - lib_file.write( - line4[0] + "\n" + line4[1] + "\n" + - self.template["start_draw"] + "\n" - ) + sym_file.write(line4[0] + "\n" + line4[1] + "\n") draw_pos = self.template["draw_pos"] draw_pos = draw_pos.split() - draw_pos[4] = str( - int(draw_pos[4]) - self.findBlockSize() * self.inc_size) + + draw_pos = \ + [w.replace('comp_name', f"{self.modelname}_0_1") for w in draw_pos] + draw_pos[8] = str(float(draw_pos[8]) + # previously it is (-) + float(self.findBlockSize() * self.inc_size)) + draw_pos_rec = draw_pos[8] + self.template["draw_pos"] = ' '.join(draw_pos) - lib_file.write(self.template["draw_pos"] + "\n") + sym_file.write( + self.template["draw_pos"] + "\n" + self.template["start_draw"] + + " \"" + f"{self.modelname}_1_1\"" + "\n" + ) input_port = self.template["input_port"] input_port = input_port.split() @@ -256,59 +281,60 @@ class AutoSchematic: self.portName[i] + str(int(outputs[i - self.input_length]) - j - 1)) - # print("INPUTS AND OUTPUTS ") - # print("INPUTS:"+inputName) - # print("OUTPUTS:"outputName) - # print(inputs) - # print(outputs) - inputs = self.char_sum(inputs) outputs = self.char_sum(outputs) total = inputs + outputs port_list = [] + + # Set input & output port + input_port[4] = draw_pos_rec + output_port[4] = draw_pos_rec + j = 0 for i in range(total): if (i < inputs): - input_port[1] = inputName[i] - input_port[2] = str(i + 1) - input_port[4] = str(int(input_port[4]) - self.dist_port) + input_port[9] = f"\"{inputName[i]}\"" + input_port[13] = f"\"{str(i + 1)}\"" + input_port[4] = \ + str(float(input_port[4]) - float(self.dist_port)) input_list = ' '.join(input_port) port_list.append(input_list) j = j + 1 else: - output_port[1] = outputName[i - inputs] - output_port[2] = str(i + 1) - output_port[4] = str(int(output_port[4]) - self.dist_port) + output_port[9] = f"\"{outputName[i - inputs]}\"" + output_port[13] = f"\"{str(i + 1)}\"" + output_port[4] = \ + str(float(output_port[4]) - float(self.dist_port)) output_list = ' '.join(output_port) port_list.append(output_list) for ports in port_list: - lib_file.write(ports + "\n") - lib_file.write( - self.template["end_draw"] + "\n" + - self.template["end_def"] + "\n\n\n" + sym_file.write(ports + "\n") + sym_file.write( + self.template["end_draw"] + "\n\n\n"+")" ) - + sym_file.close() os.chdir(cwd) -# beginning the PortInfo Class containing Port Information class PortInfo: - - # initialising the variables + ''' + The class contains port information + ''' def __init__(self, model, modelpath): self.modelname = model.modelname - # self.model_loc = model.parser.get('NGVERI', 'DIGITAL_MODEL') self.bit_list = [] self.port_name = [] self.input_len = 0 self.modelpath = modelpath - # getting the port information from connection_info.txt def getPortInfo(self): + ''' + getting the port information from `connection_info.txt` + ''' input_list = [] output_list = [] read_file = open(self.modelpath + 'connection_info.txt', 'r') @@ -336,8 +362,7 @@ class PortInfo: input_list.append(line.split()) if out_items: output_list.append(line.split()) - # print(input_list) - # print(output_list) + for in_list in input_list: self.bit_list.append(in_list[2]) self.port_name.append(in_list[0]) diff --git a/src/projManagement/Kicad.py b/src/projManagement/Kicad.py index 8c92c06b..833f075e 100644 --- a/src/projManagement/Kicad.py +++ b/src/projManagement/Kicad.py @@ -10,10 +10,10 @@ # BUGS: --- # NOTES: --- # AUTHOR: Fahim Khan, fahim.elex@gmail.com -# MODIFIED: Rahul Paknikar, rahulp@iitb.ac.in +# MODIFIED: Rahul Paknikar, Partha Singh Roy # ORGANIZATION: eSim Team at FOSSEE, IIT Bombay # CREATED: Tuesday 17 February 2015 -# REVISION: Sunday 26 July 2020 +# REVISION: Thursday 29 Jun 2023 # ========================================================================= import os @@ -25,7 +25,7 @@ from PyQt5 import QtWidgets class Kicad: """ - This class called the Kicad Schematic,KicadtoNgspice Converter,Layout + This class called the Kicad Schematic, KicadtoNgspice Converter, Layout editor and Footprint Editor Initialise validation, appconfig and dockarea @@ -79,14 +79,18 @@ class Kicad: 'Kicad Schematic is called for project ' + self.projDir) except BaseException: pass - # Validating if current project is available or not + # Validating if current project is available or not if self.obj_validation.validateKicad(self.projDir): self.projName = os.path.basename(self.projDir) self.project = os.path.join(self.projDir, self.projName) - # Creating a command to run - self.cmd = "eeschema " + self.project + ".sch " + # creating a command to open schematic + self.cmd = "eeschema " + self.project + ".kicad_sch" # kicad6 file + if not os.path.exists(self.project + ".kicad_sch") \ + and os.path.exists(self.project + ".sch"): + self.cmd = "eeschema " + self.project + ".sch" # kicad4 file + self.obj_workThread.args = self.cmd self.obj_workThread.start() diff --git a/src/projManagement/newProject.py b/src/projManagement/newProject.py index 278cfbe3..10fb0cb5 100644 --- a/src/projManagement/newProject.py +++ b/src/projManagement/newProject.py @@ -94,7 +94,8 @@ class NewProjectInfo(QtWidgets.QWidget): ) self.msg.exec_() - f.write("schematicFile " + self.projName + ".sch\n") + # New KiCad v6 file extension + f.write("schematicFile " + self.projName + ".kicad_sch\n") f.close() # Now Change the current working project |