Skip to content

Instantly share code, notes, and snippets.

@rkprojects
Created July 17, 2019 06:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rkprojects/647b45754eb844d3f4197648c2c7c825 to your computer and use it in GitHub Desktop.
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.
#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