"
"Generates Symbol and Device from a text file containing a list of pin names.
"
"This version can use BSDL (Boundary Scan Description Language) files to create a Package for BGA
"
"or use a set of parameters to generate a Package.
"
"
"
"
"+ "Bei Text-Dateien wird über die Anzahl der Trennzeichen der word separator ermittelt und voreingestellt.
" +
"Um Text-Dateien (Tabellen) zu bearbeiten, gibt es folgende Möglichkeiten:
" +
"
" + "
" +
"Bei Text-Dateien kann ein Package aus der vorhandenen Use-Liste der geladenen LBR gewählt, oder über Package automatisch generiert werden.
" +
"Bei BSDL-Dateien (.bsdl) kann ebenfalls ein Package automatisch generiert werden.
" +
"Es wird überprüft ob im benutzten Package genügend Pads vorhanden sind um jeden Symbol-Pin zu verbinden.
" +
"
" +
"BGA-Package generieren (BSDL): Es wird davon ausgegangen, daß das Gehäuse symmetrisch aufgebaut ist.
" +
" - Package Width: Die Gehäuseaussenmaße (Kunststoffkörper).
" +
" - PAD Grid: Der Abstand zwischen den SMD-Pads.
" +
" - PAD Diameter: Der Durchmesser der SMD-Pads.
" +
" - Stop Mask: Ein positiver Wert erzeugt eine Stopmaske um den angegebenen Wert größer als das Pad, " +
"ein negativer Wert erzeugt eine Maske um den Betrag kleiner als das Pad.
" +
"Package generieren: Durch Angabe der Parameter in der Karte Package können zweireihige oder vierseitige Packages generiert werden.
" +
"Der Start-Parameter edit-no-description verhindert daß in der Description des Device der Hinweis " +
" edit this description eingetragen wird.
" +
"
"+ "The number of separators in the text file determins and presets the word separator.
" +
"There are the following possibilities to edit text files (spreadsheets):
" +
"
" + "
" +
"Generate a package (BSDL files only): The package is assumed to be designed symmetrically.
" +
" - Package width: The dimension of the (plastic) case .
" +
" - PAD grid: The distance between the smds.
" +
" - PAD diameter: The diameter of the smds." +
"
" +
"
", x, grid_unit, maxminxy, grid_unit);
}
if (y > maxminxy || y < -maxminxy) {
sprintf(s, " ", y, grid_unit, maxminxy, grid_unit);
}
if (s) {
if (edit_type == e_symbol) s += "Check Symbol Pin Layout: Single | Dual | Quad before exiting this ULP Use MAP?
Coordinate (%.4f) %s out of range %.4f %s
" + infile + "
and/or measures in BGA menu.";
else if (edit_type == e_pac) s += "Check pad names
" + infile + "
and/or measures in Packlage menu.";
dlgMessageBox(s, "Ok");
return -1;
}
return 0;
}
string replaceString(string source, string find, string replace) {
string result = source;
int i = strstr(source, find);
string head;
string tail;
if (i > -1) {
if(i == 0) {
head = "";
tail = strsub(source, i + strlen(find));
}
else {
head = strsub(source, 0, i);
tail = strsub(source, i + strlen(find));
}
result = head + replace + tail;
}
return result;
}
string replaceCharacter(string source, char find, char replace) {
string result = source;
int i = strchr(source, find);
string head;
string tail;
if (i > -1) {
if(i == 0) {
head = "";
tail = strsub(source, i + 1);
}
else {
head = strsub(source, 0, i);
tail = strsub(source, i + 1);
}
sprintf(result, "%s%c%s", head, replace, tail);
}
return result;
}
// cut spaces on left and on right of string 2005-10-05
string trimString(string source) {
if(!source) return source;
string result;
int i, head = 0;
for (i = 0; source[i]; i++) {
if (!isspace(source[i])) {
head = i;
break;
}
}
int send = strlen(source);
int len = send;
if (len) {
for (i = len-1; i >= 0; i--) {
if (!isspace(source[i])) {
send = i+1;
break;
}
}
}
return strsub(source, head, send-head);
}
string cleanWhitespace(string line) {
string oldtext = "";
do {
oldtext = line;
line = replaceString(line, "\t", " ");
line = replaceString(line, " ", " ");
} while (line != oldtext);
return trimString(line);
}
string spaceCharacter(string l, char c) {
string oldtext = "";
do {
oldtext = l;
l = replaceCharacter(l, c, ' ');
} while (l != oldtext);
return l;
}
string clear_line(string l) {
if(!l) return l;
int comment = strstr(l, "--"); // comment
if (comment > 0) l = strsub(l, 0, comment); // strip comment 02.06.2005
for (int n = 0; n < strlen(l); n++) {
if (l[n] == '\"' || l[n] == '(' || l[n] == ')' || l[n] == '&' ) {
l[n] = ' ';
}
else if ( l[n] == ';') l[n] = ','; // *** replace ';' with ',' for last MAP_LINE
}
l = trimString(l);
return l;
}
string cleanName(string name) {
name = cleanWhitespace(name);
name = replaceString(name, " ", "_");
name = replaceString(name, ".", "_");
name = replaceString(name, "(", "_");
name = replaceString(name, ")", "_");
name = replaceString(name, "\\", "-");
// 2009-11-12 alf@cadsoft.de
name = replaceString(name, ",", "_");
name = replaceString(name, ";", "_");
return name;
}
void replaceWord(string search, string replace) {
string s;
tinfo = " ";
dlgRedisplay();
if (search == replace) {
dlgMessageBox("!Search string equal Replace string", "Cancel");
return;
}
int found, newfound;
int ct = 0;
do {
newfound = strstr(text, search, found);
if (newfound >= 0) {
sprintf(s, "(%d)", newfound);
status(s);
text = strsub(text, 0, newfound) + replace + strsub(text, newfound+strlen(search) );
found = newfound + strlen(replace);
ct++;
}
else break;
} while (text);
status(" ");
sprintf(tinfo, "
\\n\\\nAuto generated by %s %s
\\n\\\nSource: %s';\n",
filesetext(filename(infile), ""), editMode, filename(argv[0]), Revision, filename(infile) );
devicelib += Source_file;
devicelib += "Prefix 'IC';\n";
devicelib += "Value Off;\n";
devicelib += "ADD " + symbol_name + " 'G$1' 0 NEXT (0 0);\n";
}
int i;
int index[];
string last_pin;
suffix_cnt = 0;
sort( n_pins, index, pins);
for (i = 0; i < n_pins; i++) {
if (last_pin != pins[index[i]]) {
last_pin = pins[index[i]];
suffix_cnt = 0;
}
else {
suffix_cnt++;
}
suffix[index[i]] = suffix_cnt;
}
real x = 0;
real y = 0;
real dx = 0;
real dy = -.1;
int terminal_i = 1;
int s2 = 0;
int s3 = 0;
int s4 = 0;
int rot = 0;
real spacer = .8;
if (pin_layout == k_stripe) {
s2 = (n_pins / maxStripeCnt) / 2;
s3 = maxStripeCnt / 2;
x = -1.0 * s2 + -0.2;
y = 0.1 * s3;
dx = 0.0;
dy = -0.1;
}
else if (pin_layout == k_quad) {
y = (.1 * n_pins / 4) + spacer;
s2 = (n_pins / 4) + 1;
s3 = (2 * n_pins / 4) + 1;
s4 = (3 * n_pins / 4) + 1;
}
else if (pin_layout == k_dual) {
y = .1 * n_pins / 2;
s2 = (n_pins / 2) + 1;
}
else if (pin_layout == k_dual2) {
y = .1 * n_pins / 2;
}
else {
y = .1 * n_pins;
}
for (i = 0; i < n_pins; i++) {
int pin_num = i + 1;
if (suffix[i]) {
sprintf( pin_names[i], "%s@%d", pins[i], suffix[i]);
pins[i] = pin_names[i];
}
string pin_name = pin_names[i];
string pad_name = "";
if (use_pad_names) {
if (use_pad_names == useBGA) pad_name = pad_names[i]; // use Padname as is for BGA
else if (use_pad_names == usePACwithPrefix) pad_name = pad_names[i]; // use Padname for existing Package with Prefix
devicelib += "CONNECT 'G$1." + pin_name + "' '" + pad_name + "';\n";
}
else {
string pin_num_str;
sprintf(pin_num_str, "%u", pin_num); // genberate padname by number
devicelib += "CONNECT 'G$1." + pin_name + "' '" + pad_prefix + pin_num_str + "';\n";
}
if (check_Coordinate(pin_name, x, y, "INCH", e_symbol)) {
string ck;
sprintf(ck, "Pin %s, coordinate out of range (%.4f %.4f)", pin_name, x, y);
return ck;
}
string x_str;
string y_str;
sprintf(x_str, "%.4f", round(x * 10) / 10); // set to 0.1 Inch Grid 2006-06-01
sprintf(y_str, "%.4f", round(y * 10) / 10);
partlib += "PIN '" + pin_name + "' " + pin_direc[i] + " (" + x_str + " " + y_str + ");\n";
if (rot > 0) partlib += "ROTATE (" + x_str + " " + y_str + ");\n";
if (rot > 1) partlib += "ROTATE (" + x_str + " " + y_str + ");\n";
if (rot > 2) partlib += "ROTATE (" + x_str + " " + y_str + ");\n";
x += dx;
y += dy;
terminal_i ++;
if (pin_layout == k_stripe) {
if (terminal_i > maxStripeCnt) { // 2008-12-03 correct counts
terminal_i = 1;
s2--;
x = -1.0 * s2 + -0.2;
y = 0.1 * s3;
}
}
else if (pin_layout == k_quad) {
if (terminal_i == s2) {
dy = 0;
dx = .1;
x = spacer + .1;
y = 0;
rot = 1;
}
else if (terminal_i == s3) {
dy = .1;
dx = 0;
x += spacer;
y = spacer + .1;
rot = 2;
}
else if (terminal_i == s4) {
dy = 0;
dx = -.1;
y += spacer;
x -= spacer + .1;
rot = 3;
}
}
else if (pin_layout == k_dual) {
if (terminal_i == s2) {
dy = .1;
dx = 0;
x = spacer * 3;
y = .1;
rot = 2;
}
}
else if (pin_layout == k_dual2) {
int terminal_row = (terminal_i - 1) / 2;
y = (.1 * n_pins / 2) - .1 * terminal_row;
if ((terminal_i % 2) == 1) {
x = 0;
rot = 0;
}
else {
x = spacer * 3;
rot = 2;
}
}
}
real left = .2;
real bottom = 0;
real top = (.1 * n_pins) + .1;
real right = spacer * 1.5;
if (pin_layout == k_stripe) {
; // no frame for this symbol
}
else if (pin_layout == k_quad) {
left = .2;
bottom = .2;
top = (spacer * 2) + (.1 * n_pins / 4) - .1;
right = (spacer * 2) + (.1 * n_pins / 4) - .1;
}
else if ((pin_layout == k_dual) || (pin_layout == k_dual2)) {
top = (.1 * n_pins / 2) + .1;
right = (spacer * 3) - .2;
}
real cx = ((right - left) / 2) + left - .2;
real cy = ((top - bottom) / 2) + bottom;
if (pin_layout == k_single) {
cx = right - .4;
}
string left_str;
string bottom_str;
string top_str;
string right_str;
string movexy05 = "";
string name_x;
string name_y;
string value_x;
string value_y;
if (pin_layout == k_stripe) { // place >NAME and >VALUE in stripe symbol
s2 = (n_pins / maxStripeCnt) / 2;
s3 = maxStripeCnt / 2;
x = -1.0 * s2;
y = 0.1 * s3;
sprintf(name_x, "%.4f", x - 0.2);
sprintf(name_y, "%.4f", y + .2);
sprintf(value_x, "%.4f", x - 0.2);
sprintf(value_y, "%.4f", y + .1);
}
else { // set to 0.1 Inch Grid 2006-06-01
sprintf(left_str, "%.4f", round(left * 10) / 10);
sprintf(bottom_str, "%.4f", round(bottom * 10) / 10);
sprintf(top_str, "%.4f", round(top * 10) / 10);
sprintf(right_str, "%.4f", round(right * 10) / 10);
// ** move Origin to center **
sprintf(movexy05, "GROUP (-29.9 -29.9) (29.9 -29.9) (29.9 29.9) (-29.9 29.9) (>-29.9 -29.9);\nMOVE (>%.4f %.4f) (0 0);\n",
round(((left + right) / 2) * 10) / 10,
round(((bottom + top) / 2) * 10) / 10);
sprintf(name_x, "%.4f", round(cx * 10) / 10);
sprintf(name_y, "%.4f", round(cy * 10) / 10 + .05);
sprintf(value_x, "%.4f", round(cx * 10) / 10);
sprintf(value_y, "%.4f", round(cy * 10) / 10 - .1);
// place no frame on stripe symbol
partlib += "LAYER 94;\n";
partlib += "WIRE (" + left_str + " " + bottom_str + ") (" + right_str + " " + bottom_str + ") (" + right_str + " " + top_str + ") (" + left_str + " " + top_str + ") (" + left_str + " " + bottom_str + ");\n";
}
partlib += "CHANGE SIZE .07;\n";
partlib += "LAYER 95;\n";
partlib += "TEXT \'>NAME\' (" + name_x + " " + name_y + ");\n";
partlib += "LAYER 96;\n";
partlib += "TEXT \'>VALUE\' (" + value_x + " " + value_y + ");\n";
partlib += "LAYER 94;\n";
partlib += movexy05;
partlib += "WINDOW FIT;\n";
output(symbol_file, "wtD") {
printf("%s", partlib);
}
output(device_file, "wtD") {
printf("%s", devicelib);
}
return "";
}
string viewPadname(string t, string pacname) { // 2008-11-07 return 0 or error, Cancel = check padname
int sel;
if (t) {
dlgDialog("Make Device Package") {
dlgLabel("Pads not found in parsed list.");
dlgHBoxLayout {
dlgVBoxLayout {
dlgLabel(pacname + ".PAC");
dlgTextView(t);
}
dlgVBoxLayout {
dlgLabel("Parsed from text");
dlgListView("Pads", pad_names, sel);
}
}
if (packageparameter_accept) {
dlgLabel(" Checke Pad-Name if Prefix used.");
dlgLabel(" Possibly delete PAD Prefix in BSDL-Pad Name.");
dlgLabel(" Use Text Options [Rename PAD] to rename.");
}
dlgHBoxLayout {
dlgPushButton("+OK") { dlgAccept(); if (t) t = "Check pad name(s) in package " + pacname; }
dlgPushButton("-Cancel") { dlgReject(); return "Check pad name(s) in package " + pacname; }
dlgSpacing(20);
dlgLabel(" Package is a BGA ");
dlgPushButton("Accept") { dlgAccept(); t = ""; }
dlgStretch(1);
}
};
}
return t;
}
string check_Padname(string name) {
for (int i = 0; i < n_pins; i++) {
if (name == pad_names[i]) {
name = "";
break;
}
}
if (name) name += "\n";
return name;
}
string getPackagePadCount(string pac_name) {
checkPadname = "";
int pcount = 0;
string s;
sprintf(s, " NOT found");
library(L) {
L.packages(PAC) {
if (PAC.name == pac_name) {
status("count pads " + pac_name);
PAC.contacts(C) {
checkPadname += check_Padname(C.name);
used_pad_number[pcount] = C.name; // 2008-11-07
pcount++;
}
sprintf(s, "%d Contacts", pcount);
break;
}
}
}
return s;
}
// 2008-11-07 if make package with bsdl.
// Check used all pad-names in list with on generated Package.
// Vergleiche padnamen des bsdl file mit generierten padnamen aus package.
// Alle Pad-Namen in der Liste müssen im Package vorkommen.
//
string check_pin_pad_list(int n, int p) {
status("check pads in used package");
string ti = tinfo;
tinfo = "Please wait, check pad names!";
dlgRedisplay();
string tp;
int x = 0;
for (x = 0; x < n; x++) {
int notfound = 1;
for (int i = 0; i < p; i++) {
if (used_pad_number[i] == pad_names[x]) {
notfound = 0;
break;
}
}
if (notfound) tp += pad_names[x]+"\n";
}
tinfo = ti;
dlgRedisplay();
if (tp) return "Pads not found in Package\nCheck pad name in parsed list by 'Text Options'!\n"+tp;
return tp;
}
int check_exist_sym(string symname) {
int exist = 0;
library(L) {
L.symbols(SYM) {
if (SYM.name == symname) return 1;
}
}
return 0;
}
int getSymbolPinCount(string sym_name) {
int scount = -1;
library(L) {
L.symbols(SYM) {
if (SYM.name == sym_name) {
SYM.pins(P) scount++;
scount++;
break;
}
}
}
return scount;
}
string getPackagePadPrefix(string pac_name) {
library(L) {
L.packages(PAC) {
if (PAC.name == pac_name) {
PAC.contacts(C) {
string pad_name = C.name;
int i = strstr(pad_name, "1");
if (i != -1) {
string prefix = strsub(pad_name, 0, i);
return prefix;
}
}
}
}
}
return "P$";
}
// ** collect Packages **
void coll_packages(void) {
packages[0] = " ";
n_packages = 1;
library(L) {
L.packages(PAC) {
packages[n_packages++] = PAC.name;
}
}
return;
}
// ***** change n.ts character to new character *****
void change_char_text(char text_char, char to_char, int counter) {
int cc;
int cnt = 0;
for ( int n = 0; n < strlen(text); n ++) {
if (text[n] == text_char) {
if (cnt == counter) {
text[n] = to_char;
cc++;
cnt = 0;
}
else if (counter) cnt++;
}
}
sprintf(tinfo, "
See option:
[ Replace ] character string ..... with ....", "OK");
return;
}
if (search == replace) {
dlgMessageBox("Search string = Replace string, please change!
See option:
[ Replace ] character string .... with .....", "OK");
return;
}
for ( int n = 0; n < cnt; n++) {
int pos = strstr(pad_names[n], search);
if (pos >= 0) {
pad_names[n] = strsub(pad_names[n], 0, pos) + replace + strsub(pad_names[n], pos+strlen(search) );
cntrenamed++;
}
}
gen_viewlist(cnt);
sprintf(parsed_pins, "%d pads renamed", cntrenamed);
return;
}
// 2008-07-03
void number_pins(int cnt) {
for ( int n = 0; n < cnt; n++) {
sprintf(pad_names[n], "%d", n+1);
}
gen_viewlist(cnt);
return;
}
// 2008-07-03
void set_pin_direction(int cnt) {
string pin_dir[] = {
"NC",
"IN",
"OUT",
"I/O",
"OC",
"PWR",
"PAS",
"HIZ",
"SUP"
};
int setdir = 0;
dlgDialog("Set PIN-Directon") {
dlgHBoxLayout {
dlgGroup("Direction") {
dlgRadioButton("NC", setdir);
dlgRadioButton("IN", setdir);
dlgRadioButton("OUT", setdir);
dlgRadioButton("I/O", setdir);
dlgRadioButton("OC", setdir);
dlgRadioButton("PWR", setdir);
dlgRadioButton("PAS", setdir);
dlgRadioButton("HIZ", setdir);
dlgRadioButton("SUP", setdir);
}
dlgStretch(1);
}
dlgHBoxLayout {
dlgPushButton("OK") dlgAccept();
dlgPushButton("-Cancel") { dlgReject(); return; }
dlgStretch(1);
}
};
for ( int n = 0; n < cnt; n++) {
sprintf(pin_direc[n], "%s", pin_dir[setdir]);
}
gen_viewlist(cnt);
return;
}
string ch_dir(string dir) {
string s[];
strsplit(s, dir, '\t');
if (!s[1]) s[1] = s[0];
dlgDialog("New Direction") {
dlgHBoxLayout {
dlgLabel(s[0]);
dlgLabel(" &new ");
dlgStringEdit(s[1]);
}
dlgHBoxLayout {
dlgPushButton("+OK") dlgAccept();
dlgPushButton("-Cancel") dlgReject();
dlgStretch(1);
}
};
return s[0]+"\t"+s[1];
}
// ** change direction of pin in parsed list ** 2008-04-02
void change_dir(int cnt) {
string ndir[];
int cntdirection = 0;
int found = 0;
for (int n = 0; n < cnt; n++) {
found = 0;
for (int i = 0; i < cntdirection; i++) {
if (ndir[i] == pin_direc[n]) {
found = 1;
break;
}
}
if (!found) {
ndir[cntdirection] = pin_direc[n];
cntdirection++;
}
}
string info;
sprintf(info, "found %d directions", cntdirection);
int sel;
for (int i = 0; i < cntdirection; i++) {
ndir[i] += "\t" + ndir[i];
}
int Result = dlgDialog("Change Direction") {
dlgLabel(info);
dlgListView("Direction\tnew", ndir, sel) ndir[sel] = ch_dir(ndir[sel]);
dlgHBoxLayout {
dlgPushButton("+OK") dlgAccept();
dlgPushButton("-Cancel") dlgReject();
dlgStretch(1);
}
};
if (!Result) return;
for (n = 0; n < cnt; n++) {
string s[];
for (int i = 0; i < cntdirection; i++) {
strsplit(s, ndir[i], '\t');
if (pin_direc[n] == s[0]) {
pin_direc[n] = s[1];
break;
}
}
}
gen_viewlist(cnt);
return;
}
// *** generate package for NOT BGA ***
void gen_package(string PacName) {
real mpad_stand_out = pad_stand_out; // 2005-12-01 save parameter for display
real mypad_length = ypad_length;
real mxpad_length = xpad_length;
real center_offset;
int middle = cnt_side % 2;
if (middle) {
center_offset = cnt_side / 2 * basic_pad_grid;
}
else {
center_offset = cnt_side / 2 * basic_pad_grid - basic_pad_grid / 2;
}
real pin_length = (xA_pac - xD_pac) / 2;
string h;
real k; // koordinate for Pad line
real xcoord, ycoord;
string SMDdirection;
string pad_rect;
int padnumber = 1;
sprintf(h, "EDIT %s.PAC;\n", PacName); // 2005-11-03 alf@cadsoft,de
paccmd += h;
sprintf(h, "GRID %s %.4f ON;\n", genpac_grid, grid_val/2); // 2008-11-07 set actual grid to generate package
paccmd += h;
sprintf(h, "SET WIRE_BEND 2;\n");
paccmd += h;
sprintf(h, "CHANGE ROUNDNESS %.0f;\n", roundness_restring);
paccmd += h;
sprintf(h, "CHANGE LAYER 1;\n");
paccmd += h;
// ** make SMD or PAD ** 2005-12-01
if (smd_pad) {
pad_stand_out = 0; // no offset from mechanical-pin to pad-drill
ypad_length = 0;
sprintf(h, "CHANGE DRILL %.4f;\n", xpad_length); // PAD drill diameter
paccmd += h;
sprintf(h, "CHANGE SHAPE %s;\n", PadShape[pad_shape]);
paccmd += h;
sprintf(h, "CHANGE DIAMETER %.4f;\n", xpad_length + roundness_restring);
paccmd += h;
xpad_length = 0; // 2005-12-01
}
else {
sprintf(h, "CHANGE SMD %.4f %.4f;\n", SMD_diameter, SMD_diameter);
paccmd += h;
}
switch (pad_layout) { // check Package PAD placement
case 0 : // ### quad package with Pin 1 on TOP of LEFT side (corner) ###
for (int q = 0; q < 4; q++) {
for (int n = 0; n < cnt_side; n++) {
k = n * basic_pad_grid - center_offset;
switch(q) {
case 0 : // 1. quadrant 1.-Pad TOP of LEFT side
sprintf(SMDdirection, " %.4f %.4f ", xpad_length, ypad_length);
ycoord = k * -1;
xcoord = -xA_pac / 2 - pad_stand_out + xpad_length/2;
pin_length = (xA_pac - xD_pac) / 2;
sprintf(pad_rect, "LAYER 51;\nRECT (%.4f %.4f) (%.4f %.4f);\n",
-xA_pac/2, ycoord - pad_width/2,
-xA_pac/2 + pin_length, ycoord + pad_width/2
);
break;
case 1 : // 2. quadrant
sprintf(SMDdirection, " %.4f %.4f ", ypad_length, xpad_length);
xcoord = k;
ycoord = -xA_pac / 2 - pad_stand_out + xpad_length/2;
pin_length = (yA_pac - yD_pac) / 2;
sprintf(pad_rect, "LAYER 51;\nRECT (%.4f %.4f) (%.4f %.4f);\n",
xcoord - pad_width/2, -yA_pac/2,
xcoord + pad_width/2, -yA_pac/2 + pin_length
);
break;
case 2 : // 3. quadrant
sprintf(SMDdirection, " %.4f %.4f ", xpad_length, ypad_length);
xcoord = xA_pac / 2 + pad_stand_out - xpad_length/2;
ycoord = k;
pin_length = (xA_pac - xD_pac) / 2;
sprintf(pad_rect, "LAYER 51;\nRECT (%.4f %.4f) (%.4f %.4f);\n",
xA_pac/2, ycoord - pad_width/2,
xA_pac/2 - pin_length, ycoord + pad_width/2
);
break;
case 3 : // 4. quadrant
sprintf(SMDdirection, " %.4f %.4f ", ypad_length, xpad_length);
xcoord = k * -1;
ycoord = xA_pac / 2 + pad_stand_out - xpad_length/2;
pin_length = (yA_pac - yD_pac) / 2;
sprintf(pad_rect, "LAYER 51;\nRECT (%.4f %.4f) (%.4f %.4f);\n",
xcoord - pad_width/2, yA_pac/2,
xcoord + pad_width/2, yA_pac/2 - pin_length
);
break;
}
if (smd_pad) { // 2005-12-01
sprintf(h, "PAD '%d' (%.4f %.4f);\n", padnumber, xcoord, ycoord);
}
else {
sprintf(h, "SMD %s '%d' (%.4f %.4f);\n", SMDdirection, padnumber, xcoord, ycoord);
}
paccmd += h;
paccmd += pad_rect;
sprintf(used_pad_number[padnumber], "%d", padnumber); // 2008-11-07 for check package pad names
padnumber++;
}
}
sprintf(h, "LAYER 21;\nWIRE .2032 (%.4f %.4f) (%.4f %.4f);\n",
-xD_pac/2 + package_wire_width,
yD_pac/2 - mark_length,
-xD_pac/2 + mark_length,
yD_pac/2 - package_wire_width
);
paccmd += h;
break;
case 1 : // ### quad package with Pin 1 on MIDDLE of LEFT side ###
for (int qm = 0; qm < 5; qm++) {
for (int n = 0; n < cnt_side; n++) {
k = n * basic_pad_grid - center_offset;
switch(qm) {
case 0 : // 1. quadrant 1.-Pad MIDDLE of LEFT side
if (n >= cnt_side/2 - 0.5) {
sprintf(SMDdirection, " %.4f %.4f ", xpad_length, ypad_length);
xcoord = -xA_pac / 2 - pad_stand_out + xpad_length/2;
ycoord = k * -1;
pin_length = (xA_pac - xD_pac) / 2;
sprintf(pad_rect, "LAYER 51;\nRECT (%.4f %.4f) (%.4f %.4f);\n",
-xA_pac/2, ycoord - pad_width/2,
-xA_pac/2 + pin_length, ycoord + pad_width/2
);
}
else SMDdirection = ""; // ** clear, do not genearate line **
break;
case 1 : // 2. quadrant
sprintf(SMDdirection, " %.4f %.4f ", ypad_length, xpad_length);
xcoord = k;
ycoord = -xA_pac / 2 - pad_stand_out + xpad_length/2;
pin_length = (yA_pac - yD_pac) / 2;
sprintf(pad_rect, "LAYER 51;\nRECT (%.4f %.4f) (%.4f %.4f);\n",
xcoord - pad_width/2, -yA_pac/2,
xcoord + pad_width/2, -yA_pac/2 + pin_length
);
break;
case 2 : // 3. quadrant
sprintf(SMDdirection, " %.4f %.4f ", xpad_length, ypad_length);
xcoord = xA_pac / 2 + pad_stand_out - xpad_length/2;
ycoord = k;
pin_length = (xA_pac - xD_pac) / 2;
sprintf(pad_rect, "LAYER 51;\nRECT (%.4f %.4f) (%.4f %.4f);\n",
xA_pac/2, ycoord - pad_width/2,
xA_pac/2 - pin_length, ycoord + pad_width/2
);
break;
case 3 : // 4. quadrant
sprintf(SMDdirection, " %.4f %.4f ", ypad_length, xpad_length);
xcoord = k * -1;
ycoord = yA_pac / 2 + pad_stand_out - xpad_length/2;
pin_length = (yA_pac - yD_pac) / 2;
sprintf(pad_rect, "LAYER 51;\nRECT (%.4f %.4f) (%.4f %.4f);\n",
xcoord - pad_width/2, yA_pac/2,
xcoord + pad_width/2, yA_pac/2 - pin_length
);
break;
case 4 : // 1. quadrant pad right side to middle
if (n < cnt_side/2 - 0.5) {
sprintf(SMDdirection, " %.4f %.4f ", xpad_length, ypad_length);
ycoord = k * -1;
xcoord = -xA_pac / 2 - pad_stand_out + xpad_length/2;
pin_length = (xA_pac - xD_pac) / 2;
sprintf(pad_rect, "LAYER 51;\nRECT (%.4f %.4f) (%.4f %.4f);\n",
-yA_pac/2, ycoord - pad_width/2,
-yA_pac/2 + pin_length, ycoord + pad_width/2
);
}
else SMDdirection = ""; // ** clear, do not genearate line **
break;
}
if (SMDdirection) {
if (smd_pad) { // 2005-12-01
sprintf(h, "PAD '%d' (%.4f %.4f);\n", padnumber, xcoord, ycoord);
}
else {
sprintf(h, "SMD %s '%d' (%.4f %.4f);\n", SMDdirection, padnumber, xcoord, ycoord);
}
paccmd += h;
paccmd += pad_rect;
sprintf(used_pad_number[padnumber], "%d", padnumber); // 2008-11-07 for check package pad names
padnumber++;
}
}
}
sprintf(h, "LAYER 21;\nCIRCLE .2032 (%.4f 0) (%.4f 0);\n",
-xD_pac/2 + xpad_length + mark_length/2,
-xD_pac/2 + xpad_length + mark_length
);
paccmd += h;
break;
case 2 : // dual in line package
for (int qd = 0; qd < 2; qd++) {
for (int n = 0; n < cnt_side; n++) {
k = n * basic_pad_grid - center_offset;
switch(qd) {
case 0 : // 1. quadrant
sprintf(SMDdirection, " %.4f %.4f ", xpad_length, ypad_length);
ycoord = k * -1;
xcoord = -xA_pac / 2 - pad_stand_out + xpad_length/2;
pin_length = (xA_pac - xD_pac) / 2;
sprintf(pad_rect, "LAYER 51;\nRECT (%.4f %.4f) (%.4f %.4f);\n",
-xA_pac/2, ycoord - pad_width/2,
-xA_pac/2 + pin_length, ycoord + pad_width/2
);
break;
case 1 : // 2. quadrant
sprintf(SMDdirection, " %.4f %.4f ", xpad_length, ypad_length);
xcoord = xA_pac / 2 + pad_stand_out - xpad_length/2;
ycoord = k;
pin_length = (xA_pac - xD_pac) / 2;
sprintf(pad_rect, "LAYER 51;\nRECT (%.4f %.4f) (%.4f %.4f);\n",
xA_pac/2, ycoord - pad_width/2,
xA_pac/2 - pin_length, ycoord + pad_width/2
);
break;
}
if (smd_pad) { // 2005-12-01
sprintf(h, "PAD '%d' (%.4f %.4f);\n", padnumber, xcoord, ycoord);
}
else {
sprintf(h, "SMD %s '%d' (%.4f %.4f);\n", SMDdirection, padnumber, xcoord, ycoord);
}
paccmd += h;
paccmd += pad_rect;
sprintf(used_pad_number[padnumber], "%d", padnumber); // 2008-11-07 for check package pad names
padnumber++;
}
}
sprintf(h, "LAYER 21;\nARC CCW .2032 (%.4f %.4f) (%.4f %.4f) (%.4f %.4f);\n",
-mark_length,
yD_pac/2 - package_wire_width,
mark_length,
yD_pac/2 - package_wire_width,
mark_length,
yD_pac/2 - package_wire_width
);
paccmd += h;
break;
}
sprintf(h, "SET WIRE_BEND 0;\n");
paccmd += h;
sprintf(h, "CHANGE LAYER 21;\n");
paccmd += h;
sprintf(h, "WIRE .2032 (%.4f %.4f) (%.4f %.4f) (%.4f %.4f);\n",
-xD_pac /2 + package_wire_width,
-yD_pac /2 + package_wire_width,
xD_pac /2 - package_wire_width,
yD_pac /2 - package_wire_width,
-xD_pac /2 + package_wire_width,
-yD_pac /2 + package_wire_width
);
paccmd += h;
// mark edge on pin 1
sprintf(h, "SET WIRE_BEND 2;\n");
paccmd += h;
sprintf(h, "CHANGE SIZE %.2f;\n", textsize);
paccmd += h;
sprintf(h, "CHANGE LAYER 25;\n");
paccmd += h;
sprintf(h, "TEXT >NAME (%.4f %.4f);\n",
-xA_pac/2, yA_pac/2 + textsize*0.5);
paccmd += h;
sprintf(h, "CHANGE LAYER 27;\n");
paccmd += h;
sprintf(h, "TEXT >VALUE (%.4f %.4f);\n",
-xA_pac/2, -yA_pac/2 - textsize*1.5);
paccmd += h;
sprintf(h, "DESCRIPTION '%s
\\n\\\nAuto generated by %s %s
\\n';\n",
PacName, filename(argv[0]), Revision );
paccmd += h;
pad_stand_out = mpad_stand_out; // 2005-12-01
ypad_length = mypad_length;
xpad_length = mxpad_length;
return;
}
void display_error(string er) { // 2008-11-07 display error text/messages
dlgDialog(filename(argv[0])) {
dlgHBoxLayout dlgSpacing(300);
dlgLabel("Errors");
dlgHBoxLayout {
dlgVBoxLayout dlgSpacing(500);
dlgTextView(er);
}
dlgHBoxLayout {
dlgPushButton("Back") dlgAccept();
dlgPushButton("Cancel") { dlgReject(); exit(-2); }
dlgStretch(1);
}
};
}
// Generate BGA Pad list to generate only GBA package 2009-10-16
void genBGAlist(int x, int y) {
int existnpadname = 0;
do {
existnpadname++;
} while(bga_pad_name[existnpadname]);
string bga1 = "";
string bga2 = bga_pad_name[0];
string s;
int n = 0;
for (int ny = 0; ny < y; ny++) {
for (int nx = 0; nx < x; nx++) {
if (ny >= existnpadname) {
int firstcolumn = ny / existnpadname;
if (firstcolumn) {
bga2 = bga_pad_name[ny - firstcolumn*(existnpadname)];
bga1 = bga_pad_name[firstcolumn-1];
}
else bga2 = bga_pad_name[ny];
}
else bga2 = bga_pad_name[ny];
sprintf(pins_pads_direc[n], " \t%s%s%d\t ", bga1, bga2, nx+1);
sprintf(pad_names[n],"%s%s%d", bga1, bga2, nx+1);
n++;
}
}
pins_pads_direc[n] = ""; // clear last line in array
n_pins = x*y; // pins "parsed"!
sprintf(parsed_pins, "%d BGA pads generated", n_pins);
return;
}
void genBGA_PadList(void) { // 2009-10-16
dlgDialog("Generate BGA pad list") {
if (!is_bsdl) {
dlgLabel("Generate PAD list without a BSDL file to autogenerate a BGA package.");
dlgHBoxLayout {
dlgGridLayout {
dlgCell(0,0) dlgLabel("pad lines ");
dlgCell(0,1) dlgIntEdit(cntBGApadY, 1 , 500);
dlgCell(1,0) dlgLabel("pads in row ");
dlgCell(1,1) dlgIntEdit(cntBGApadX, 1 ,500);
}
dlgStretch(1);
}
dlgHBoxLayout {
dlgPushButton("OK") { dlgAccept(); only_generate_bga = 1; genBGAlist(cntBGApadX, cntBGApadY); }
dlgPushButton("CANCEL") dlgReject();
dlgStretch(1);
}
}
else {
dlgLabel("Can not use this option, while bsdl file is loaded!");
dlgHBoxLayout {
dlgPushButton("OK") dlgAccept();
dlgStretch(1);
}
}
};
return;
}
// *** main ***
if (library) {
string rf[]; // 2008-11-07 check exist remember file
int nrf = fileglob(rf, filedir(argv[0])+rememberLastPathFile);
if (nrf) nrf = fileread(rememberBSDLpath, rf[0]);
if (argv[1] == "edit-no-description") editMode = "";
string packinfo = "";
int make_Symbol;
int make_Device;
real m_pac_width = pac_width; // 2006-06-01 alf
real m_grid_val = grid_val;
real m_SMD_diameter = SMD_diameter;
real m_MaskRestring = MaskRestring;
real m_CreamDiameter = CreamDiameter;
int exact_include = 0;
string del_line;
int delColumn = 1;
string st[];
int separator_counter = 2;
string c_separator;
int start_line, x_line;
int cc;
tinfo = " ";
int do_copy = 1;
string search, replace;
coll_packages();
package_name = ""; // default
string PadCount;
sprintf(String_separator, "%c", Word_separator);
string cmd;
int result = dlgDialog("Make Symbol / Device / Package ") {
dlgHBoxLayout {
dlgLabel("&File:");
dlgStringEdit(infile);
dlgPushButton("&Browse") {
infile = dlgFileOpen("Select a File", rememberBSDLpath, "*.bsdl *.bsd *.bsm *.txt");
if (infile) { // 23.03.2005
// 2008-11-07 write last path in file to remember for next start
output(filedir(argv[0])+rememberLastPathFile, "wt") printf("%s", filedir(infile));
readText(infile);
status(" "); // 2008-11-07 // clear display working
if (is_bsdl) {
make_Symbol = 1;
make_Device = 1;
make_Package = 1;
if (check_exist_pac(package_name)) make_Package = 0; // 2009-10-12 reset flag
m_pac_width = pac_width;
m_grid_val = grid_val;
m_SMD_diameter = SMD_diameter;
m_MaskRestring = MaskRestring;
m_CreamDiameter = CreamDiameter;
}
}
}
}
dlgHBoxLayout {
dlgVBoxLayout dlgSpacing(300); // 2005-01-26
dlgVBoxLayout {
dlgHBoxLayout dlgSpacing(500);
dlgHBoxLayout {
dlgLabel("Text");
dlgStretch(1);
dlgLabel(bsdl_package_name, 1);
}
dlgTextEdit(text);
}
dlgVBoxLayout {
dlgSpacing(25);
dlgPushButton(" &<<-- Copy") {
if (is_bsdl) {
do_copy = 0;
if (dlgMessageBox("!BSDL file loaded. Are you sure you want to copy listing to text?", "Ok", "Cancel") == 0) do_copy = 1;
}
if (do_copy) {
text = "";
for (int i = 0; i < n_pins; i++) {
if (i) text += "\n";
text += pin_names[i] + String_separator + pad_names[i];
if (pin_direc[i]) text += String_separator + pin_direc[i];
}
//infile = ""; // delete filename while text is copy from list // 2008-11-07 use for DESCRIPTION
is_bsdl = 0;
delete_empty_lines();
tinfo = "Text is a copy of pin/pad list.";
dlgRedisplay();
}
}
dlgStretch(1);
dlgPushButton("S&ort PAD") {
parsed_pins = "sorted by pad";
sorting_pad(n_pins);
gen_viewlist(n_pins);
}
dlgStretch(1);
dlgPushButton("So&rt PIN") {
parsed_pins = "sorted by pin";
sorting_pin(n_pins);
gen_viewlist(n_pins);
}
dlgStretch(1);
dlgPushButton("Parse -->&>") {
parsed_pins = "parsing text, please wait...";
dlgRedisplay();
if (!is_bsdl) filter_text(use_pad_names);
else dlgMessageBox(";Only text files can be parsed. BSDL files will be parsed automatically!", "Ok");
}
}
dlgVBoxLayout {
dlgHBoxLayout dlgSpacing(200);
dlgListView( "Pins\tPads\tDirect.", pins_pads_direc, select, sorting);
}
}
dlgHBoxLayout {
dlgVBoxLayout {
dlgSpacing(18);
}
dlgLabel(tinfo, 1);
dlgStretch(1);
dlgLabel(parsed_pins, 1);
dlgSpacing(8);
}
dlgTabWidget {
dlgTabPage("Ma&ke") { // #######################################
dlgSpacing(12);
dlgHBoxLayout {
dlgSpacing(8);
dlgGridLayout {
dlgCell(1,0) dlgCheckBox("&Symbol", make_Symbol);
dlgCell(1,1) dlgLabel(" &Name ");
dlgCell(1,2) { dlgStringEdit(symbol_name); dlgLabel(".SYM"); }
dlgCell(2,0) dlgVBoxLayout dlgSpacing(64);
dlgCell(3,0) dlgCheckBox("Pa&ckage ", make_Package);
dlgCell(3,1) dlgLabel(" Na&me ");
dlgCell(3,2) { dlgStringEdit(package_name); dlgLabel(".PAC"); }
dlgCell(4,1) dlgLabel("&Variant ");
dlgCell(4,2) dlgStringEdit(pac_variant_name);
dlgCell(5,1) dlgVBoxLayout dlgSpacing(24);
dlgCell(5,2) dlgSpacing(200);
dlgCell(7,0) dlgCheckBox("&Device", make_Device)
if(make_Device) {
if (!device_name) {
dlgMessageBox("! Define a Device name", "OK");
make_Device = 0;
}
}
dlgCell(7,1) dlgLabel(" Nam&e ");
dlgCell(7,2) { dlgStringEdit(device_name); dlgLabel(".DEV"); }
}
dlgSpacing(16);
dlgGroup("Symbol Pin Layout") {
dlgGridLayout {
dlgCell(1, 1) dlgRadioButton("Sing&le", pin_layout) pinCntInfo = " ";
dlgCell(0, 1) dlgLabel("");
dlgCell(1, 3) dlgRadioButton("Dual &1", pin_layout) pinCntInfo = " ";
dlgCell(0, 3) dlgLabel("");
dlgCell(1, 5) dlgRadioButton("Dual &2", pin_layout) pinCntInfo = " ";
dlgCell(0, 5) dlgLabel("");
dlgCell(1, 7) dlgRadioButton("&Quad", pin_layout) pinCntInfo = " ";
dlgCell(0, 7) dlgLabel("");
dlgCell(1, 9) dlgRadioButton("Str&ipe", pin_layout) pinCntInfo = "
" +
"or accept BGA parameter,
or Use an existing Package.
");
dlgHBoxLayout {
dlgStretch(1);
dlgLabel("quick file option");
dlgStretch(1);
}
dlgStretch(1);
dlgHBoxLayout {
dlgStretch(1);
dlgPushButton("Load") {
string fl = infile;
if (!fl) fl = path_epf[1] + "/~make.txt"; // 2008-05-20
else {
if (strstr(fl, "/~make.txt") < 0) { // 2009-02-18
fl = filedir(infile) + "~make.txt";
}
}
string fn[]; // 2008-11-07 first check if file exist
int fc = fileglob(fn, fl);
if (!fc) {
fl = dlgFileOpen(fl, "", "*.txt *.*");
}
if (fl) {
infile = fl; // 2008-11-07 show actual filename
int cnt = fileread(text, fl);
parsed_pins = "Text loaded:"+fl;
}
}
dlgPushButton("Save") {
string fs = infile;
if (!fs) fs = path_epf[1] + "/~make.txt"; // 2008-03-26
else {
if (strstr(fs, "/~make.txt") < 0) { // 2009-02-18
fs = filedir(infile) + "~make.txt";
}
}
output(fs, "wt") printf("%s", text);
parsed_pins = "Text saved:"+fs;
}
dlgPushButton("Save as") {
string fsa = dlgFileSave("BSDL-Text-Save", path_epf[1], "*.txt");
if (fsa) {
output(fsa, "wt") printf("%s", text);
parsed_pins = "Text saved:"+fsa;
}
}
}
}
dlgStretch(1);
}
dlgSpacing(8);
}
}
}
dlgHBoxLayout {
dlgSpacing(8);
dlgPushButton("&Help") dlgMessageBox(Help, "Ok");
dlgStretch(1);
dlgLabel(Revision);
}
};
if (result) {
if (make_Symbol) cmd += "SCRIPT '" + symbol_file + "';\nWIN FIT;\n";
if (make_Device) cmd += "SCRIPT '" + device_file + "';\nWIN FIT;";
}
exit(cmd);
}
else {
dlgMessageBox("!This is no Library!\nThis program can only work in the Library editor.");
exit(0);
}