Created
July 17, 2019 06:10
-
-
Save rkprojects/647b45754eb844d3f4197648c2c7c825 to your computer and use it in GitHub Desktop.
Lists unconnected pins in the Eagle schematic editor and generates a report file in the schematic directory.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#usage "en: <b>Lists unconnected pins in the Schematic " | |
"and generates a report file in the schematic directory.</b>" | |
"<p>To disable report generation, set variable<br>" | |
"<b>enable_output_report = 0</b><br>" | |
"Default report file name: <b>unconnected_pins.txt</b><br>" | |
"To change default report file name, set variable<br>" | |
"<b>report_filename = your_choice</b></p>" | |
"<p>To mark a pin as no connect in schematic, add a new attribute to the part and set:<br>" | |
"<b>Attribute Name</b> = Name of the Pin<br>" | |
"<b>Attribute Value</b> = nc<br>" | |
"Example, if a part <b>J1</b> has a pin named <b>IO2</b> then set<br>" | |
"<b>Attribute Name</b> = IO2<br>" | |
"<b>Attribute Value</b> = nc<br></p>" | |
"<p>Tested on Eagle version 9.3.2, 9.4.2 free edition only.<br>" | |
"This ULP program comes with ABSOLUTELY NO WARRANTY OF ANY KIND. USE AT YOUR OWN RISK.</p>" | |
"<p>Author: Ravikiran Bukkasagara, contact@ravikiranb.com</p>" | |
string version = "1.0"; | |
/* | |
Set this variable to 0, to disable writing | |
unconnected pin list to a report file | |
in the schematic file directory. | |
*/ | |
int enable_output_report = 1; | |
string report_filename = "unconnected_pins.txt"; | |
string connected_pins[]; | |
string connected_pins_flattened = ""; | |
string unconnected_pins_flattened = ""; | |
int unconnected_pin_count = 0; | |
string unconnected_pins[]; | |
string PIN_ATTR_NC_VALUE = "nc"; | |
string PIN_ATTR_NC_PREFIX = ""; | |
string pin_list; | |
string toAlphaNumName(string s) { | |
int length; | |
//get aplha numeric part of the name | |
int start = strxstr(s, "[a-zA-Z0-9_-]+", 0, length); | |
if (start >= 0) | |
return strsub(s, start, length); | |
else | |
return s; | |
} | |
if (schematic == 0) { | |
dlgMessageBox(":This ulp is meant for Schematics only!"); | |
exit(-1); | |
} | |
schematic(SCH) { | |
SCH.sheets(SH) { | |
SH.nets(N) { | |
N.segments(SEG) { | |
SEG.pinrefs(P) { | |
string line; | |
sprintf(line, "%s.%s\n", | |
P.part.name, | |
P.pin.name); | |
connected_pins_flattened += line; | |
} | |
} | |
} | |
} | |
SCH.modules(M) { | |
M.sheets(SH) { | |
SH.nets(N) { | |
N.segments(SEG) { | |
SEG.pinrefs(P) { | |
string connection; | |
sprintf(connection, "%s.%s.%s\n", | |
M.name, | |
P.part.name, | |
P.pin.name); | |
connected_pins_flattened += connection; | |
} | |
} | |
} | |
} | |
} | |
if (strsplit(connected_pins, connected_pins_flattened, '\n') <= 0) { | |
dlgMessageBox(":Failed to build connected pin list."); | |
exit(-1); | |
} | |
// Check for unconnected pins inside modules. | |
SCH.modules(M) { | |
M.parts(P) { | |
P.instances(I) { | |
I.gate.symbol.pins(PIN) { | |
if (PIN.direction == PIN_DIRECTION_NC) { | |
continue; | |
} | |
string an_name = toAlphaNumName(PIN.name); | |
if (P.attribute[an_name]) { | |
if (strlwr(P.attribute[PIN_ATTR_NC_PREFIX+an_name]) == PIN_ATTR_NC_VALUE) { | |
continue; | |
} | |
} | |
string full_pin_name; | |
sprintf(full_pin_name, "%s.%s.%s", | |
M.name, | |
P.name, | |
PIN.name); | |
if (lookup(connected_pins, full_pin_name, 0) == "") { | |
string line; | |
sprintf(line, "%s\t%s\t%d\t%s\n", | |
P.name, | |
PIN.name, | |
I.sheet, | |
M.name); | |
unconnected_pins_flattened += line; | |
unconnected_pin_count++; | |
} | |
} | |
} | |
} | |
} | |
// Check for unconnected pins outside modules. | |
SCH.parts(P) { | |
P.instances(I) { | |
I.gate.symbol.pins(PIN) { | |
if (PIN.direction == PIN_DIRECTION_NC) { | |
continue; | |
} | |
string an_name = toAlphaNumName(PIN.name); | |
if (P.attribute[an_name]) { | |
if (strlwr(P.attribute[PIN_ATTR_NC_PREFIX+an_name]) == PIN_ATTR_NC_VALUE) { | |
continue; | |
} | |
} | |
string full_pin_name; | |
sprintf(full_pin_name, "%s.%s", | |
P.name, | |
PIN.name); | |
if (lookup(connected_pins, full_pin_name, 0) == "") { | |
string line; | |
sprintf(line, "%s\t%s\t%d\n", | |
P.name, | |
PIN.name, | |
I.sheet); | |
unconnected_pins_flattened += line; | |
unconnected_pin_count++; | |
} | |
} | |
} | |
} | |
if (unconnected_pin_count > 0) | |
if (strsplit(unconnected_pins, unconnected_pins_flattened, '\n') <= 0) { | |
dlgMessageBox(":Failed to build unconnected pin list."); | |
exit(-1); | |
} | |
string header = "Part\tPin\tSheet\tModule"; | |
string status_msg; | |
sprintf(status_msg, "Unconnected Pin Count: %d", unconnected_pin_count); | |
status(status_msg); | |
string path_elements[]; | |
int n = strsplit(path_elements, SCH.name, '/'); | |
path_elements[n-1] = report_filename; | |
string report_path = strjoin(path_elements, '/'); | |
if (unconnected_pin_count > 0) { | |
dlgDialog("Unconnected Pin List") { | |
int selected = -1; | |
if (enable_output_report) { | |
dlgLabel("Report File: " + report_path); | |
} | |
dlgListView(header, unconnected_pins, selected); | |
dlgHBoxLayout { | |
dlgStretch(1); | |
dlgPushButton("+Close") { | |
dlgAccept(); | |
} | |
} | |
}; | |
} | |
if (enable_output_report) { | |
int now = time(); | |
output(report_path) { | |
printf("Date: %s\n", t2string(now)); | |
printf("Unconnected Pin Count: %d\n", unconnected_pin_count); | |
if (unconnected_pin_count > 0) { | |
printf("\n%s\n", header); | |
printf("%s", unconnected_pins_flattened); | |
} | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment