Eeschema: add python script netlist_form_OrcadPcb2.py and netlist_form_pads-pcb-asc.py
to replace netlist_form_OrcadPcb2.xsl and netlist_form_pads-pcb.asc.xsl
This commit is contained in:
parent
bc8245ca7b
commit
7e2abf545b
|
@ -286,6 +286,16 @@ class libpart():
|
|||
fieldNames.append( f.get('field','name') )
|
||||
return fieldNames
|
||||
|
||||
def getPinList(self):
|
||||
"""Return a list of pins in play for this libpart.
|
||||
"""
|
||||
pinList = []
|
||||
pins = self.element.getChild('pins')
|
||||
if pins:
|
||||
for f in pins.getChildren():
|
||||
pinList.append( f )
|
||||
return pinList
|
||||
|
||||
def getDatasheet(self):
|
||||
return self.getField("Datasheet")
|
||||
|
||||
|
@ -361,20 +371,21 @@ class comp():
|
|||
def getValue(self):
|
||||
return self.element.get("value")
|
||||
|
||||
def getField(self, name, libraryToo=True):
|
||||
"""Return the value of a field named name. The component is first
|
||||
def getField(self, name, aLibraryToo = True):
|
||||
"""
|
||||
Return the value of a field named name. The component is first
|
||||
checked for the field, and then the components library part is checked
|
||||
for the field. If the field doesn't exist in either, an empty string is
|
||||
returned
|
||||
|
||||
Keywords:
|
||||
name -- The name of the field to return the value for
|
||||
libraryToo -- look in the libpart's fields for the same name if not found
|
||||
aLibraryToo -- look in the libpart's fields for the same name if not found
|
||||
in component itself
|
||||
"""
|
||||
|
||||
field = self.element.get("field", "name", name)
|
||||
if field == "" and libraryToo and self.libpart:
|
||||
if field == "" and aLibraryToo and self.libpart:
|
||||
field = self.libpart.getField(name)
|
||||
return field
|
||||
|
||||
|
@ -394,15 +405,25 @@ class comp():
|
|||
def getRef(self):
|
||||
return self.element.get("comp", "ref")
|
||||
|
||||
def getFootprint(self, libraryToo=True):
|
||||
'''
|
||||
return the footprint name. if empty and aLibraryToo = True, return the
|
||||
footprint name from libary
|
||||
'''
|
||||
def getFootprint(self, aLibraryToo = True):
|
||||
ret = self.element.get("footprint")
|
||||
if ret == "" and libraryToo and self.libpart:
|
||||
|
||||
if ret == "" and aLibraryToo and self.libpart:
|
||||
ret = self.libpart.getFootprint()
|
||||
|
||||
return ret
|
||||
|
||||
def getDatasheet(self, libraryToo=True):
|
||||
'''
|
||||
return the datasheet name. if empty and aLibraryToo = True, return the
|
||||
datasheet name from libary
|
||||
'''
|
||||
def getDatasheet(self, aLibraryToo = True):
|
||||
ret = self.element.get("datasheet")
|
||||
if ret == "" and libraryToo and self.libpart:
|
||||
if ret == "" and aLibraryToo and self.libpart:
|
||||
ret = self.libpart.getDatasheet()
|
||||
return ret
|
||||
|
||||
|
@ -420,6 +441,41 @@ class comp():
|
|||
def getDescription(self):
|
||||
return self.element.get("libsource", "description")
|
||||
|
||||
'''
|
||||
return the netname of the pin aPinNum in netlist aNetlist
|
||||
if aSkipEmptyNet = True, net having only one pin will return a empty name
|
||||
'''
|
||||
def getPinNetname(self, aPinNum, aNetlist, aSkipEmptyNet):
|
||||
ref = self.getRef()
|
||||
|
||||
for net in aNetlist.nets:
|
||||
net_name = net.get( "net", "name" )
|
||||
|
||||
item_cnt = 1
|
||||
netitems = net.children
|
||||
|
||||
for node in netitems:
|
||||
curr_item_ref = node.get( "node", "ref" )
|
||||
|
||||
if curr_item_ref == ref:
|
||||
curr_pin = node.get( "node", "pin" )
|
||||
|
||||
if aPinNum == curr_pin:
|
||||
if aSkipEmptyNet: #ensure at least 2 pins are in net
|
||||
pin_count = 0
|
||||
|
||||
for curr_node in netitems:
|
||||
pin_count += 1
|
||||
|
||||
if pin_count > 1:
|
||||
return net_name
|
||||
|
||||
return ""
|
||||
else:
|
||||
return net_name
|
||||
|
||||
return "?"
|
||||
|
||||
|
||||
class netlist():
|
||||
""" Kicad generic netlist class. Generally loaded from a kicad generic
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
#
|
||||
# Example python script to generate a BOM from a KiCad generic netlist
|
||||
#
|
||||
|
||||
"""
|
||||
@package
|
||||
Output: old OrcadPcb2 netlist format
|
||||
Sorted By: Ref
|
||||
|
||||
Command line:
|
||||
python "pathToFile/netlist_form_OrcadPcb2.py" "%I" "%O.net"
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
# Import the KiCad python helper module
|
||||
import kicad_netlist_reader
|
||||
import sys
|
||||
|
||||
# A helper function to convert a UTF8/Unicode/locale string read in netlist
|
||||
# for python2 or python3 (Windows/unix)
|
||||
def fromNetlistText( aText ):
|
||||
if sys.platform.startswith('win32'):
|
||||
try:
|
||||
return aText.encode('utf-8').decode('cp1252')
|
||||
except UnicodeDecodeError:
|
||||
return aText
|
||||
else:
|
||||
return aText
|
||||
|
||||
# Generate an instance of a generic netlist, and load the netlist tree from
|
||||
# the command line option. If the file doesn't exist, execution will stop
|
||||
netlist = kicad_netlist_reader.netlist(sys.argv[1])
|
||||
|
||||
# Open a file to write to, if the file cannot be opened output to stdout
|
||||
# instead
|
||||
try:
|
||||
f = open(sys.argv[2], 'wb')
|
||||
except IOError:
|
||||
e = "Can't open output file for writing: " + sys.argv[2]
|
||||
print(__file__, ":", e, sys.stderr)
|
||||
f = sys.stdout
|
||||
|
||||
components = netlist.getInterestingComponents()
|
||||
|
||||
row =""
|
||||
|
||||
''' Netlist header:
|
||||
( { EESchema Netlist Version 1.1 02/09/2021 11:10:00
|
||||
Eeschema (5.99.0-12178-ge03257b55f-dirty)}
|
||||
'''
|
||||
''' Generate line ( { EESchema Netlist Version 1.1 <time> '''
|
||||
row += '( { EESchema Netlist Version 1.1 ' + netlist.getDate() + '\n'
|
||||
''' Generate line Eeschema <eeschema version> '''
|
||||
row += 'Eeschema ' + netlist.getTool() + ' }\n\n'
|
||||
|
||||
|
||||
'''
|
||||
This template read each component and creates lines:
|
||||
( 3EBF7DBD $noname U1 74LS125
|
||||
... pin list ...
|
||||
)
|
||||
and calls "create_pin_list" template to build the pin list
|
||||
'''
|
||||
|
||||
for c in components:
|
||||
fp_name = c.getFootprint( False )
|
||||
|
||||
if fp_name == "":
|
||||
fp_name = "$noname"
|
||||
|
||||
row += "( " + c.getTimestamp() + ' ' + fp_name
|
||||
row += ' ' + c.getRef()
|
||||
row += ' ' + c.getValue()
|
||||
row += '\n'
|
||||
|
||||
'''
|
||||
generate pin list
|
||||
The pin list from library description is something like
|
||||
<pins>
|
||||
<pin num="1" type="passive"/>
|
||||
<pin num="2" type="passive"/>
|
||||
</pins>
|
||||
Output pin list is ( <pin num> <net name> )
|
||||
something like
|
||||
( 1 VCC )
|
||||
( 2 GND )
|
||||
for not connected pins:
|
||||
( 3 ? )
|
||||
'''
|
||||
lib = c.getLibPart()
|
||||
pinlist = lib.getPinList()
|
||||
|
||||
for pin in pinlist:
|
||||
pin_num = pin.get('pin','num')
|
||||
row += " ( " + pin_num + " "
|
||||
netname = c.getPinNetname( pin_num, netlist, True )
|
||||
|
||||
if netname == "":
|
||||
netname = "?"
|
||||
|
||||
row += netname
|
||||
row += " )\n"
|
||||
|
||||
row += ')\n'
|
||||
|
||||
row += '\n)\n'
|
||||
|
||||
f.write(row.encode('utf-8'))
|
||||
f.close()
|
|
@ -8,7 +8,7 @@
|
|||
Sorted By: Ref
|
||||
|
||||
Command line:
|
||||
python "pathToFile/bom_txt_sorted_by_ref.py" "%I" "%O.rinf"
|
||||
python "pathToFile/netlist_form_cadstar.py" "%I" "%O.frp"
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
@ -50,7 +50,8 @@ row += ".HEA" + '\n'
|
|||
''' Generate line .TIM <time> '''
|
||||
row += '.TIM ' + netlist.getDate() + '\n'
|
||||
''' Generate line .APP <eeschema version> '''
|
||||
row += '.APP ' + netlist.getTool() + '\n\n'
|
||||
row += '.APP ' + netlist.getTool() + '\n'
|
||||
row += '.TYP FULL' + '\n\n'
|
||||
|
||||
|
||||
''' Generate list of component
|
||||
|
@ -62,8 +63,10 @@ row += '.APP ' + netlist.getTool() + '\n\n'
|
|||
for c in components:
|
||||
row += ".ADD_COM " + " " + c.getRef() + " \"" + c.getValue() + "\""
|
||||
|
||||
if c.getFootprint() != "":
|
||||
row += " \"" + c.getFootprint() + "\""
|
||||
fp_name = c.getFootprint( False )
|
||||
|
||||
if fp_name != "":
|
||||
row += " \"" + fp_name + "\""
|
||||
|
||||
row += '\n'
|
||||
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
#
|
||||
# Example python script to generate a BOM from a KiCad generic netlist
|
||||
#
|
||||
|
||||
"""
|
||||
@package
|
||||
Output: PADS format netlist
|
||||
Sorted By: Ref
|
||||
|
||||
Command line:
|
||||
python "pathToFile/netlist_form_pads-pcb-asc.py" "%I" "%O.net"
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
# Import the KiCad python helper module
|
||||
import kicad_netlist_reader
|
||||
import sys
|
||||
|
||||
# A helper function to convert a UTF8/Unicode/locale string read in netlist
|
||||
# for python2 or python3 (Windows/unix)
|
||||
def fromNetlistText( aText ):
|
||||
if sys.platform.startswith('win32'):
|
||||
try:
|
||||
return aText.encode('utf-8').decode('cp1252')
|
||||
except UnicodeDecodeError:
|
||||
return aText
|
||||
else:
|
||||
return aText
|
||||
|
||||
# Generate an instance of a generic netlist, and load the netlist tree from
|
||||
# the command line option. If the file doesn't exist, execution will stop
|
||||
netlist = kicad_netlist_reader.netlist(sys.argv[1])
|
||||
|
||||
# Open a file to write to, if the file cannot be opened output to stdout
|
||||
# instead
|
||||
try:
|
||||
f = open(sys.argv[2], 'wb')
|
||||
except IOError:
|
||||
e = "Can't open output file for writing: " + sys.argv[2]
|
||||
print(__file__, ":", e, sys.stderr)
|
||||
f = sys.stdout
|
||||
|
||||
components = netlist.getInterestingComponents()
|
||||
|
||||
row =""
|
||||
|
||||
''' Netlist header '''
|
||||
row += "!PADS-POWERPCB-V2.0-MILS!" + '\n'
|
||||
row += '*PART*' + '\n'
|
||||
|
||||
|
||||
''' Generate list of component
|
||||
for each component create lines like
|
||||
C1 Capacitor_THT:CP_Axial_L18.0mm_D6.5mm_P25.00mm_Horizontal
|
||||
C2 Capacitor_THT:CP_Axial_L18.0mm_D6.5mm_P25.00mm_Horizontal
|
||||
'''
|
||||
|
||||
for c in components:
|
||||
row += " " + c.getRef()
|
||||
|
||||
fp_name = c.getFootprint( False )
|
||||
|
||||
if fp_name != "":
|
||||
row += " " + fp_name
|
||||
|
||||
row += '\n'
|
||||
|
||||
'''
|
||||
generate for each net create lines like
|
||||
*SIGNAL* /CLOCK-RB6
|
||||
P2.27
|
||||
P3.39
|
||||
'''
|
||||
nets = netlist.getNets()
|
||||
|
||||
row += '\n*NET*' + '\n'
|
||||
|
||||
for net in nets:
|
||||
# count the number of pads in net. nets with only one pad are skipped
|
||||
netitems = net.children
|
||||
pad_count = 0
|
||||
|
||||
for node in netitems:
|
||||
pad_count += 1
|
||||
|
||||
netitems = net.children
|
||||
|
||||
if pad_count > 1:
|
||||
row += "*SIGNAL* " + net.get( "net", "name" ) + '\n'
|
||||
|
||||
for node in netitems:
|
||||
row += node.get('node','ref') + '.' + node.get('node','pin') + '\n'
|
||||
|
||||
row += '*END*\n'
|
||||
|
||||
f.write(row.encode('utf-8'))
|
||||
f.close()
|
Loading…
Reference in New Issue