You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
442 lines
14 KiB
Plaintext
442 lines
14 KiB
Plaintext
#usage "<b>Export DIF 4.0 format</b><p>"
|
|
"This format is used for production and test purposes. It has been defined by Digitaltest GmbH.<p>"
|
|
"Run the ULP from the board editor and get the file <i>boardname.dif</i>.<p>"
|
|
"Please have a look at the \"user definable parameters\" section of the program."
|
|
"<p>"
|
|
"<author>Author: support@cadsoft.de</author>"
|
|
|
|
// THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED
|
|
|
|
|
|
// 2005-02-28: Corrected output for mirrored components
|
|
// Added "File Save" dialog
|
|
// by support@cadsoft.de
|
|
// 2005-11-09: Corrected Y Coordinate, was always minus
|
|
// 2008-05-27: Corrected relativ coordinates if package rotate in 0.1 degree
|
|
// by alf@cadsoft.de
|
|
|
|
|
|
string REVISION = "2.00";
|
|
|
|
////////////////// 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); // correct sign, was always minus 2005.11.09 alf@cadsoft.de
|
|
}
|
|
//-----------------------------------------------------
|
|
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.mirror) { // flip back if mirrored
|
|
x = -x;
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
//-----------------------------------------------------
|
|
string padtype(UL_PACKAGE P, 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_PACKAGE P,UL_CONTACT C) {
|
|
int i = 0;
|
|
for (i = 0; t[i]; i++) {
|
|
if (t[i] == padtype(P,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 %s Revision %s\" }\n", EAGLE_VERSION, EAGLE_RELEASE, filename(argv[0]),REVISION);
|
|
printf(" { VERSION %s }\n", difversion);
|
|
printf(" { DATE %d/%d/%d }\n", t2day(t),t2month(t)+1,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.package, C))
|
|
new = 0; // padtype exists
|
|
}
|
|
if (new) {
|
|
t[j] = padtype(E.package, 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");
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// 2008-05-27: Corrected relativ coordinates if package rotate in 0.1 degree alf@cadsoft.de
|
|
|
|
void picturePackage(UL_PACKAGE P, int ox, int oy) {
|
|
real angle, delta = 15;
|
|
|
|
P.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)
|
|
printf(" { L (%d,%d)\n", u2x(W.arc.x1-ox), u2y(W.arc.y1-oy));
|
|
angle = W.arc.angle1 + delta;
|
|
while (angle < W.arc.angle2) {
|
|
printf(" (%d,%d)\n",
|
|
u2x((W.arc.xc-ox+W.arc.radius) * cos(deg2arc(angle))),
|
|
u2y((W.arc.yc-oy+W.arc.radius) * sin(deg2arc(angle))));
|
|
angle += delta;
|
|
}
|
|
|
|
printf(" (%d,%d)\n }\n", u2x(W.arc.x2-ox), u2y(W.arc.y2-oy));
|
|
}
|
|
else {
|
|
printf(" { Linie (%d,%d) ", u2x(W.x1-ox), u2y(W.y1-oy));
|
|
printf("(%d,%d) }\n", u2x(W.x2-ox), u2y(W.y2-oy));
|
|
}
|
|
}
|
|
}
|
|
P.circles(W) {
|
|
if (W.layer == LAYER_TPLACE || W.layer == LAYER_TDOCU || W.layer == LAYER_BPLACE || W.layer == LAYER_BDOCU) {
|
|
printf(" { L (%d,%d)\n", u2x(W.x-ox+W.radius), u2y(W.y-oy));
|
|
angle = 0;
|
|
while (angle < 360) {
|
|
printf(" (%d,%d)\n", u2x((W.x-ox+W.radius) * cos(deg2arc(angle))), u2y((W.y-oy+W.radius) * sin(deg2arc(angle))));
|
|
angle += delta;
|
|
}
|
|
printf(" (%d,%d)\n }\n", u2x(W.x-ox+W.radius), u2y(W.y-oy));
|
|
}
|
|
}
|
|
P.rectangles(W) {
|
|
if (W.layer == LAYER_TPLACE || W.layer == LAYER_TDOCU || W.layer == LAYER_BPLACE || W.layer == LAYER_BDOCU) {
|
|
printf(" { L (%d,%d)\n", u2x(W.x1-ox), u2y(W.y1-oy));
|
|
printf(" (%d,%d)\n", u2x(W.x2-ox), u2y(W.y1-oy));
|
|
printf(" (%d,%d)\n", u2x(W.x2-ox), u2y(W.y2-oy));
|
|
printf(" (%d,%d)\n", u2x(W.x1-ox), u2y(W.y2-oy));
|
|
printf(" (%d,%d)\n }\n", u2x(W.x1-ox), u2y(W.y1-oy));
|
|
}
|
|
}
|
|
int nr_of_pins = 0;
|
|
P.contacts(C) { nr_of_pins++;}
|
|
if (nr_of_pins) {
|
|
printf(" { PINS %d\n", nr_of_pins);
|
|
}
|
|
P.contacts(C) {
|
|
printf(" (%d,%d) %d\n", u2x(C.x-ox), u2y(C.y-oy), padindex(P, C)); // Pin IDs
|
|
}
|
|
if (nr_of_pins) {
|
|
printf(" }\n");
|
|
}
|
|
printf(" { SPECIFIC \"%s\" }\n", validname(P.name)+"_"+validname(P.library)); // PACK.NAME
|
|
printf(" }\n"); // end pic n
|
|
return;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////
|
|
void pictures(UL_BOARD B) {
|
|
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
|
|
picturePackage(E.package, E.x, E.y);
|
|
}
|
|
}
|
|
}
|
|
|
|
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, ""));
|
|
|
|
string fileName = dlgFileSave("Save DIF 4.0 File", filesetext(B.name, ".dif"), "*.dif");
|
|
if (fileName == "") exit(0);
|
|
|
|
output(fileName) {
|
|
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);
|
|
}
|