#usage "Export IPC-D-356 data format\n" "

" "Generates a netlist in IPC-D-356 format from the current board." "

" "Please take care of net names. IPC-D-356 does not allow more than 14 characters! " "Written for EAGLE 4.1. " "

" "IPC-D-356 syntax generated according to the specifications of
" "
" "IPC-D-356 Simplified
" "Written by Rich Nedbal
" "DownStream Technologies, LLC
" "
" "

" "Author: support@cadsoft.de" #require 4.1602 // THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED // // Release 1.0 -- November 2003 // Release 1.0.1 -- May 2006, Added source of specification (ric) // Release 2.0.0 -- 2012-02-29, values calculated with u2inch (alf) // Release 2.0.1 -- 2012-03-13, corrected calulation of diameter (alf) // now generate the same data as the original ulp up to V5. // Release 2.0.2 -- corrected line 82, multiplicator 1000 -> 10000 // Release 2.1.0 -- Added support for blind and buried vias (JG) // Release 2.2.0 -- Added support for long net names(JG) // Release 2.3.0 -- Added length checks for Reference Designators(JG) /* TODO LIST * * Add length checks to every parameter, the file format is very sensitive to long names */ string Version = "2.3.0"; string fileName, RefDes, Access, Xpolarity, Ypolarity, RestOfLine, NoDiameter, EmptySignal, Alias[], temp[], SigName; int i = 0, n, Alias_counter = 0, TypeNumber, Diameter, Xcoord, Ycoord, RectDataX, RectDataY, Angle; void Header(UL_BOARD B) { printf("C IPC-D-356 generated by %s\n", EAGLE_SIGNATURE); printf("C Database %s -- Exported at %s\n", B.name, t2string(time())); //printf("C ULP-Version %s : Values = Inch/1000\n", Version); // 2012-03-13 printf("C \n"); printf("P JOB EAGLE %d.%d NETLIST, DATE: %s\n", EAGLE_VERSION, EAGLE_RELEASE , t2string(time())); printf("P UNITS CUST 0\n"); printf("P DIM N\n"); printf("P IMAGE PRIMARY\n"); B.signals(S) { //Check if signal name exceeds 14 character limit if (strlen(S.name) >= 14) { sprintf(Alias[i],"%s;WZ%03d", S.name, Alias_counter); //1000 Long netnames allowed strsplit(temp,Alias[i],';'); printf("P NNAME%s %-58s\n",temp[1],temp[0]); i++; Alias_counter++; } if (Alias_counter > 999) { dlgMessageBox("You have more than 1000 net names longer than 14 characters, please use shorter names in order to generate the netlist"); exit (0); } } } void TestRecord(UL_BOARD B) { B.signals(S) { S.vias(V) { Access = "A00"; //This value is irrelevant for blind/buried vias but is necessary, to conform to the format if (V.start == 1 && V.end == 16) { TypeNumber = 317 ; } else { TypeNumber = 307 ; //Blind or buried vias } RefDes = "VIA"; Diameter = round(u2inch(V.drill)*1000); Xcoord = round(u2inch(V.x)*10000); Ycoord = round(u2inch(V.y)*10000); if (Xcoord >= 0) Xpolarity = "X "; if (Xcoord < 0) Xpolarity = "X-"; if (Ycoord >= 0) Ypolarity = "Y "; if (Ycoord < 0) Ypolarity = "Y-"; //Check for long net name, if it is long use alias otherwise use name if (strlen(S.name) >= 14) { SigName = lookup(Alias, S.name, 1, ';'); } else { SigName = S.name; } if (V.start == 1 && V.end == 16) { RectDataX = RectDataY = round(u2inch(V.diameter[V.start])*10000); RestOfLine = " " ; // 13 blanks to fill up 80 characters printf("%3d%-14s %-12sD%4dP%-3s%2s%6d%2s%6dX%4dY%4d%-13s\n", TypeNumber, SigName, RefDes, Diameter, Access, Xpolarity, abs(Xcoord), Ypolarity, abs(Ycoord), RectDataX, RectDataY, RestOfLine); } else if (V.start == 1 && V.end != 16) { //Blind Vias with access from the top RectDataX = RectDataY = round(u2inch(V.diameter[V.start])*10000); RestOfLine = " " ; // 13 blanks to fill up 80 characters EmptySignal = " "; // Blank name for the 027 record printf("%3d%-14s %-12sD%4dP%-3s%2s%6d%2s%6d L%02dL%02d\n", TypeNumber, SigName, RefDes, Diameter, Access, Xpolarity, abs(Xcoord), Ypolarity, abs(Ycoord), V.start, V.end); printf("%03d%-14s %-12s %-3s%2s%6d%2s%6dX%4dY%4d%-13s\n", 027, EmptySignal, RefDes, Access, Xpolarity, abs(Xcoord), Ypolarity, abs(Ycoord), RectDataX, RectDataY, RestOfLine); } else if (V.start != 1 && V.end == 16) { //Blind Vias with access from the bottom RectDataX = RectDataY = round(u2inch(V.diameter[V.end])*10000); RestOfLine = " " ; // 13 blanks to fill up 80 characters EmptySignal = " "; // Blank name for the 027 record printf("%3d%-14s %-12sD%4dP%-3s%2s%6d%2s%6d L%02dL%02d\n", TypeNumber, SigName, RefDes, Diameter, Access, Xpolarity, abs(Xcoord), Ypolarity, abs(Ycoord), V.start, V.end); printf("%03d%-14s %-12s %-3s%2s%6d%2s%6dX%4dY%4d%-13s\n", 027, EmptySignal, RefDes, Access, Xpolarity, abs(Xcoord), Ypolarity, abs(Ycoord), RectDataX, RectDataY, RestOfLine); } else { //Buried Vias printf("%3d%-14s %-12sD%4dP%-3s%2s%6d%2s%6d L%02dL%02d\n", TypeNumber, SigName, RefDes, Diameter, Access, Xpolarity, abs(Xcoord), Ypolarity, abs(Ycoord), V.start, V.end); } } } B.elements(E) { E.package.contacts(C) { if (C.pad) { TypeNumber = 317 ; RefDes = E.name; //Check for long reference designator if (strlen(RefDes) > 6) { int result; string toolong_mesg = RefDes+"is too long a reference designator. Would you like to truncate it to 6 characters? No will exit the ULP"; if(dlgMessageBox(toolong_mesg,"&Yes","&No") == 0) { RefDes = strsub(RefDes, 0, 5); } else { exit(0); } } Diameter = round(u2inch(C.pad.drill)*1000); Access = "A00"; Xcoord = round(u2inch(C.pad.x)*10000); Ycoord = round(u2inch(C.pad.y)*10000); if (Xcoord >= 0) Xpolarity = "X "; if (Xcoord < 0) Xpolarity = "X-"; if (Ycoord >= 0) Ypolarity = "Y "; if (Ycoord < 0) Ypolarity = "Y-"; if (C.pad.elongation == 0) RectDataX = RectDataY = round(u2inch(C.pad.diameter[LAYER_TOP])*10000); else { // if (C.pad.elongation != 0) RectDataX = round(u2inch(C.pad.diameter[LAYER_TOP])*10000); RectDataY = round((u2inch(C.pad.diameter[LAYER_TOP])*10000) * (C.pad.elongation / 100) + u2inch(C.pad.diameter[LAYER_TOP])*10000); } Angle = round(C.pad.angle); RestOfLine = " "; //Check for long net name, if it is long use alias otherwise use name if (strlen(C.pad.signal) >= 14) { SigName = lookup(Alias, C.pad.signal, 1, ';'); } else { SigName = C.pad.signal; } printf("%3d%-14s %-6s-%-4s D%4dP%-3s%2s%6d%2s%6dX%4dY%4dR%3d%-9s\n", TypeNumber, SigName, RefDes, C.pad.name, Diameter, Access, Xpolarity, abs(Xcoord), Ypolarity, abs(Ycoord), RectDataX, RectDataY, Angle, RestOfLine); } if (C.smd) { TypeNumber = 327 ; RefDes = E.name; NoDiameter = " "; // No drill ==> coloum 33-38 empty if (C.smd.layer == 1) Access = "A01"; if (C.smd.layer == 16) Access = "A16"; Xcoord = round(u2inch(C.smd.x)*10000); Ycoord = round(u2inch(C.smd.y)*10000); if (Xcoord >= 0) Xpolarity = "X "; if (Xcoord < 0) Xpolarity = "X-"; if (Ycoord >= 0) Ypolarity = "Y "; if (Ycoord < 0) Ypolarity = "Y-"; RectDataX = round(u2inch(C.smd.dx) * 10000) ; RectDataY = round(u2inch(C.smd.dy) * 10000) ; Angle = round(C.smd.angle); RestOfLine = " "; //Check for long net name, if it is long use alias otherwise use name if (strlen(C.smd.signal) >= 14) { SigName = lookup(Alias, C.smd.signal, 1, ';'); } else { SigName = C.smd.signal; } printf("%3d%-14s %-6s-%-4s %-6s%-3s%2s%6d%2s%6dX%4dY%4dR%3d%-9s\n", TypeNumber, SigName, RefDes, C.smd.name, NoDiameter, Access, Xpolarity, abs(Xcoord), Ypolarity, abs(Ycoord), RectDataX, RectDataY, Angle, RestOfLine); } } // B.holes(H) TypeNumber = 347 ; printf("%d", TypeNumber); // E.package.holes(H) TypeNumber = 347 ; printf("%d", TypeNumber); } } void EndOfFile(void) { printf("999\n"); } //==========main=========== if (board) { board(B) { fileName = dlgFileSave("Save IPC-D-356 File", filesetext(B.name, ".ipc"), "*.ipc"); if (fileName == "") exit(0); output(fileName) { Header(B); TestRecord(B); EndOfFile(); } } } else { dlgMessageBox("!Start this ULP in a Board."); exit (0); }