#usage "Export DIF 4.0 format\n" "

" "This format is used for production and test purposes. It has been defined by Digitaltest GmbH.

" "Run the ULP from the board editor and get the file boardname.dif.

" "Please have a look at the \"user definable parameters\" section of the program." "

" "Author: support@cadsoft.de" // THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED ////////////////// user definable parameters //////////////////////////////////////////////// int pad_layer = 1; // change to 16 if pad parameters should be taken from bottom layer int nr_of_layers = 2; int fill_polygons = 1; // set to 0 if polygons are not to be filled // if set to 1, please make sure the width parameter of the polygons // is >> 0 // make also sure the polygon filling is visible in EAGLE ///////////////////////////////////////////////////////////////////////////////////////////// string difversion = "4.0"; string jobname, pcbname, shapename[], // package names t[]; // padtypes real ang2, x, y; int nr_of_nets = 0, nr_of_comps = 0, i, new, sx, dummy_pad_code; //----------------------------------------------------- string validname (string s) { int i; for (i = 0; s[i]; i++) { if (s[i] == ',') s[i] = '_'; if (s[i] == ';') s[i] = '_'; if (s[i] == ')') s[i] = '_'; // add further substitutions here } return s; } //----------------------------------------------------- int u2u(int x) { // resolution 1/10000 mm // return u2mil(x); // mil return x; } //----------------------------------------------------- int u2x(int x) { return u2u(x); } //----------------------------------------------------- int u2y(int x) { return -u2u(x); } //----------------------------------------------------- real deg2arc(int x) { // degree to arc return x*PI/180; } //----------------------------------------------------- int u2ang(real x) { if (x > 360) x = x -360; return x; } //---------------------------------------------------- void relco (UL_ELEMENT E, int xt, int yt) { // change if finer rotation possible xt = xt - E.x; yt = yt - E.y; // move part origin to 0,0 if (E.angle == 0) { // rotate to zero position x = xt; y = yt; } if (E.angle == 90) { x = yt; y = -xt; } if (E.angle == 180) { x = -xt; y = -yt; } if (E.angle == 270) { x = -yt; y = xt; } if (E.mirror) { // flip back if mirrored y = -y; } } //----------------------------------------------------- string padtype(UL_ELEMENT E, UL_CONTACT C) { string s; int pdi; if (C.pad) { pdi = u2u(C.pad.diameter[pad_layer]); sprintf(s, "pad_%d_%d_%d", C.pad.shape[pad_layer], u2u(C.pad.diameter[pad_layer]), u2u(C.pad.drill)); } if (C.smd) { sprintf(s, "smd_%d_%d", u2x(C.smd.dx), u2y(C.smd.dy)); } return s; } //----------------------------------------------------- int padindex(UL_ELEMENT E,UL_CONTACT C) { int i = 0; for (i = 0; t[i]; i++) { if (t[i] == padtype(E,C)) return i+1; } return i; // should not be possible } //----------------------------------------------------- string viatype(UL_VIA V) { string s; int pdi; pdi = u2u(V.diameter[pad_layer]); sprintf(s, "pad_%d_%d_%d", V.shape[pad_layer], u2u(V.diameter[pad_layer]), u2u(V.drill)); return s; } //----------------------------------------------------- int viaindex(UL_VIA V) { int i = 0; for (i = 0; t[i]; i++) { if (t[i] == viatype(V)) return i+1; } return i; // should not be possible } //----------------------------------------------------- int realnet(UL_SIGNAL S) { S.contactrefs(S) return 1; return 0; } ////////////////////////////////////////////////////// void create_environment () { int t = time(); printf(" { ENVIRONMENT\n"); printf(" { SOURCE \"EAGLE %d.%02d\" }\n", EAGLE_VERSION, EAGLE_RELEASE); printf(" { VERSION %s }\n", difversion); printf(" { DATE %d/%d/%d }\n", t2day(t),t2month(t),t2year(t)); printf(" { TIME %d:%d:%d }\n", t2hour(t),t2minute(t),t2second(t)); printf(" { UNITS 1/10000 mm }\n"); printf(" { LAYER %d }\n", nr_of_layers); printf(" { TOP_LAYER 1 }\n"); printf(" { BOTTOM_LAYER 16 }\n"); printf(" { NO_NET %d }\n", nr_of_nets); printf(" { NO_COMP %d }\n", nr_of_comps); printf(" }\n"); } ////////////////////////////////////////////////////// void board_data(UL_BOARD B) { int i = 0; printf (" { BOARD\n"); printf (" { F\n"); B.wires(W) { // if board outline as wires in board i++; if (W.layer == LAYER_DIMENSION) { printf(" { L (%d,%d) (%d,%d) }\n", u2x(W.x1), u2y(W.y1), u2x(W.x2), u2y(W.y2)); } } if (i == 0) { // board contains no dim wires, try packages B.elements(E) { E.package.wires(W) { if (W.layer == LAYER_DIMENSION) { printf(" { L (%d,%d) (%d,%d) }\n", u2x(W.x1), u2y(W.y1), u2x(W.x2), u2y(W.y2)); } } } } printf (" }\n"); printf (" }\n"); } ////////////////////////////////////////////////////// void components(UL_BOARD B) { int i, pic_nr; string devname = ""; printf (" { COMPONENTS\n"); B.elements(E) { if (E.package) { printf(" { COMP\n"); printf(" { COMP_DEF\n"); printf(" { NAME %s }\n", E.name); printf(" { PART_NR %s }\n", validname(E.package.name)+"_"+validname(E.package.library)); printf(" }\n"); printf(" { PIN_DEF\n"); int issmd = 0; E.package.contacts(C) { printf(" { PIN %s { NET %s } }\n", C.name, C.signal); if (C.smd) issmd = 1; } // find picture code for (i=0; shapename[i] != validname(E.package.name)+"_"+validname(E.package.library); i++) { } pic_nr = i; printf(" }\n"); printf(" { PICTURE\n"); printf(" { ORIGIN (%d,%d) }\n", u2x(E.x), u2y(E.y)); printf(" { PIC %d }\n", pic_nr); printf(" { ROTATION %d }\n", u2ang(E.angle)); int mside = 1; if (E.mirror) { mside = 2; } printf(" { M_SIDE %d }\n", mside); if (issmd) { printf(" { KIND SMD }\n"); } /* implement later if necessary E.texts(T) { printf(" { TEXT\n"); printf(" }\n"); } */ printf(" }\n"); printf(" }\n"); } } printf(" }\n"); } ////////////////////////////////////////////////////// void pad_symbols(UL_BOARD B) { int i, j = 0, new; // j+1 = pad index; t[] contains padtypes printf (" { PAD_DEF\n"); B.elements(E) { E.package.contacts(C) { if (1 /* C.pad */) { new = 1; // padtype not generated yet for (i = 0; t[i]; i++) { if (t[i] == padtype(E,C)) new = 0; // padtype exists } if (new) { t[j] = padtype(E,C); j++; if (C.pad) printf(" { PAD %d\n { SIZE %d }\n { DRILL %d }\n }\n", j,abs(u2u(C.pad.diameter[pad_layer])),abs(u2u(C.pad.drill))); if (C.smd) printf(" { PAD %d\n { SIZE %d }\n { DRILL 0 }\n }\n", j, min(abs(u2x(C.smd.dx)), abs(u2y(C.smd.dy)))); } } } } B.signals(S) { S.vias(V) { new = 1; for (i = 0; t[i]; i++) { if (t[i] == viatype(V)) new = 0; // padtype exists } if (new) { t[j] = viatype(V); j++; dummy_pad_code = j; // find pad code for dummy pad printf(" { PAD %d\n { SIZE %d }\n { DRILL %d }\n }\n", j,u2u(V.diameter[pad_layer]),u2u(V.drill)); } } } printf (" }\n"); } ////////////////////////////////////////////////////// void pictures(UL_BOARD B) { int i, xll, yll; real angle, delta = 15; printf ("{ PIC_LIB\n"); sx=0; B.elements(E) { if (E.package) { new = 1; // padtype not generated yet for (i = 0; shapename[i]; i++) { if (shapename[i] == validname(E.package.name)+"_"+validname(E.package.library)) new = 0; // ident. package exists } if (new) { shapename[sx] = validname(E.package.name)+"_"+validname(E.package.library); printf(" { PIC %d\n",sx++); // PACKAGE NR E.package.wires(W) { if (W.layer == LAYER_TPLACE || W.layer == LAYER_TDOCU || W.layer == LAYER_BPLACE || W.layer == LAYER_BDOCU) { if (W.arc) { // process arcs (done with wire segments) relco(E, W.arc.x1, W.arc.y1); // x, y = relative coords printf(" { L (%d,%d)\n", u2x(x), u2y(y)); angle = W.arc.angle1 + delta; while (angle < W.arc.angle2) { relco(E, W.arc.xc+W.arc.radius * cos(deg2arc(angle)), W.arc.yc+W.arc.radius * sin(deg2arc(angle))); printf(" (%d,%d)\n", u2x(x), u2y(y)); angle += delta; } relco(E, W.arc.x2, W.arc.y2); printf(" (%d,%d)\n }\n", u2x(x), u2y(y)); } else { relco(E, W.x1, W.y1); // x, y = relative coords printf(" { L (%d,%d) ", u2x(x), u2y(y)); relco(E, W.x2, W.y2); printf("(%d,%d) }\n", u2x(x), u2y(y)); } } } E.package.circles(W) { if (W.layer == LAYER_TPLACE || W.layer == LAYER_TDOCU || W.layer == LAYER_BPLACE || W.layer == LAYER_BDOCU) { relco(E, W.x+W.radius, W.y); // x, y = relative coords printf(" { L (%d,%d)\n", u2x(x), u2y(y)); angle = 0; while (angle < 360) { relco(E, W.x+W.radius * cos(deg2arc(angle)), W.y+W.radius * sin(deg2arc(angle))); printf(" (%d,%d)\n", u2x(x), u2y(y)); angle += delta; } relco(E, W.x+W.radius, W.y); printf(" (%d,%d)\n }\n", u2x(x), u2y(y)); } } E.package.rectangles(W) { if (W.layer == LAYER_TPLACE || W.layer == LAYER_TDOCU || W.layer == LAYER_BPLACE || W.layer == LAYER_BDOCU) { relco(E, W.x1, W.y1); // x, y = relative coords xll = x; yll = y; relco(E, W.x2, W.y2); printf(" { L (%d,%d)\n", u2x(xll), u2y(yll)); printf(" (%d,%d)\n", u2x(x), u2y(yll)); printf(" (%d,%d)\n", u2x(x), u2y(y)); printf(" (%d,%d)\n", u2x(xll), u2y(y)); printf(" (%d,%d)\n }\n", u2x(xll), u2y(yll)); } } int nr_of_pins = 0; E.package.contacts(C) { nr_of_pins++;} if (nr_of_pins) { printf(" { PINS %d\n", nr_of_pins); } E.package.contacts(C) { relco(E, C.x, C.y); // rel. coord. of pins printf(" (%d,%d) %d\n", u2x(x), u2y(y), padindex(E, C)); // Pin IDs } if (nr_of_pins) { printf(" }\n"); } printf(" { SPECIFIC \"%s\" }\n", validname(E.package.name)+"_"+validname(E.package.library)); // PACK.NAME printf(" }\n"); // end pic n } } } printf(" { PIC 999\n"); printf(" { R (0, 0) }\n"); printf(" { PINS 1 (0, 0) %d }\n", dummy_pad_code); printf(" }\n"); printf("}\n"); } ////////////////////////////////////////////////////// void nets(UL_BOARD B) { printf(" { NET_DEF\n"); B.signals(S) { if (realnet(S)) { printf(" { NET %s\n", S.name); S.wires(W) { printf(" { W (%d, %d) %d %d (%d %d) %d %d }\n", u2x(W.x1), u2y(W.y1), W.layer, u2u(W.width), u2x(W.x2), u2y(W.y2), W.layer, u2u(W.width)); } S.polygons(P) { P.contours(W) { printf(" { W (%d, %d) %d %d (%d %d) %d %d }\n", u2x(W.x1), u2y(W.y1), W.layer, u2u(W.width), u2x(W.x2), u2y(W.y2), W.layer, u2u(W.width)); } if (fill_polygons) { P.fillings(W) { printf(" { W (%d, %d) %d %d (%d %d) %d %d }\n", u2x(W.x1), u2y(W.y1), W.layer, u2u(W.width), u2x(W.x2), u2y(W.y2), W.layer, u2u(W.width)); } } } S.vias(V) { printf(" { V (%d, %d) %d 1, 15 }\n", u2x(V.x), u2y(V.y), viaindex(V)); } printf(" }\n"); } } printf(" }\n"); } ////////////////////////////////////////////////////// void net_comp_count(UL_BOARD B) { nr_of_nets = 0; nr_of_comps = 0; B.signals(S) { if (realnet(S)) { nr_of_nets++; } } B.elements(E) { if (E.package) { nr_of_comps++; } } } ////////////////////////////////////////////////////// if (board) board(B) { jobname = filename(filesetext(B.name, "")); pcbname = filename(filesetext(B.name, "")); output(filesetext(B.name, ".dif")) { printf("{ JOB %s\n", jobname); printf(" { PCB %s\n", pcbname); net_comp_count(B); create_environment(); board_data(B); pad_symbols(B); pictures(B); nets(B); components(B); printf(" }\n"); printf("}\n"); } } else { dlgMessageBox("\n Start this ULP in a Board \n"); exit (0); }