neingeist
/
arduinisten
Archived
1
0
Fork 0
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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
arduinisten/eagle-5.7.0/ulp/make-symbol-device-package-...

3295 lines
117 KiB
Plaintext

#usage "<qt><nobr><b>Make Symbol, Device, Package or use Package in LBR</b>\n"
"<p>"
"Generates Symbol and Device from a text file containing a list of pin names.<br>"
"This version can use <b>BSDL</b> (<i>Boundary Scan Description Language</i>) files to create a Package for BGA<br>"
"or use a set of parameters to generate a Package.<br>"
"<p>"
"<author>Author: ed@anuff.com / librarian@cadsoft.de</author></nobr></qt>"
#require 4.1600
/*
* Copyright (c) 2004 Ed Anuff <ed@anuff.com>. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
// Rev: 1 (Eagle 4.12r04) - 2004-08-13 alf@cadsoft.de
// *****************************************************************
// Rev: 2 (Eagle 4.13) - 2004-14-09 alf@cadsoft.de
// special sorting for Pad names with 2-Alpha-Character
// *** Xilix BSM-Files without ";" in line *************************
// Xilinx = "linkage bit_vector (" and ": inout bit -- "
// BSDL = "linkage bit_vector; (" and ": inout bit; -- "
// *****************************************************************
// Rev: 3 (Eagle 4.13) - 2004-11-23 alf@cadsoft.de
// corrected parse line with "port"
// *** Xilinx BSM-Files
// "port (" - without spaces
// *** Intel .bsdl-Files
// " port (" - with spaces
// corrected Function: [Replace] character string
// *****************************************************************
// Rev: 4 (Eagle 4.13) - 2005-01-10 alf@cadsoft.de
// port: trim left spaces from string
// pars_map() corrected counter
// *****************************************************************
// Rev: 5 (Eagle 4.13) - 2005-01-27 alf@cadsoft.de
// AnalogDevice uses Tabulator not Space characters and
// some times places no space before use direction
// *****************************************************************
// Rev: 6 (Eagle 4.13) - 2005-03-23 alf@cadsoft.de
// Device and Package description font bold/italic
// *****************************************************************
// Rev: 7 (Eagle 4.14) - 2005-06-06 alf@cadsoft.de
// Accept comment "--" in line
// *****************************************************************
// Rev: 8 (Eagle 4.15) - 2005-06-28 alf@cadsoft.de
// Corrected grid and Package outlines
// allways set grid to 1.0 mm (default)
// *****************************************************************
// Rev: 9 (Eagle 4.15) - 2005-08-02 alf@cadsoft.de
// change TAB with SPACE "\t" --> " "
// Improved search end of "port" list for Xilinx-BSDL-Files
// *****************************************************************
// Rev: 10 (Eagle 4.15) - 2005-08-19 alf@cadsoft.de
// Menu to generate quad and dual pin packages
// correct port-end-parse with ");" and for AnalogDevice == "));"
// *****************************************************************
// Rev: 11 (Eagle 4.15) - 2005-10-18 alf@cadsoft.de
// new parse end of port, counts open-close Bracked
// BSDL can use multiple packages, now can select one, if more than one defined
// Also generate Symbol only
// Generate Package variant
// Scan "BSDL" in text to set BSDL-Parse-Option if any file extension
// *****************************************************************
// Rev: 12 (Eagle 4.15) - 2005-12-01 alf@cadsoft.de
// If !file use lbrname for path/script
// Correct package_name handling
// Change bit-map if select quad or dual package
// Use also thrue hole PADs for Packages
// *****************************************************************
// Rev: 13 (Eagle 4.16r1) - 2006-06-01 alf@cadsoft.de
// round coordinates to 0.1 inch in symbol
// Menu BGA: [] Accept copy local parameter to global parameter
// *****************************************************************
// Rev: 14 (Eagle 4.16r1) - 2006-06-09 alf@cadsoft.de
// Menu BGA: add Cream-Mask Parameter
// *****************************************************************
// Rev: 15 (Eagle 4.16r1) - 2006-07-06 alf@cadsoft.de
// more at 1 Pin-Pad definition in Xilinx-BSDL Files, at
// constant CP56 : PIN_MAP_STRING :=
// "TCK : K10, TDI : J10, TDO : A6, TMS : K9, " &
// *****************************************************************
// Rev: 16 (Eagle 14.16r1) - 2006-10-19 alf@cadsoft.de
// Plus menu entry: delete Pad-Prefix in BSDL-List
// Example: Xilinx - xcs20_PQ208.bsd
// Check if exist Pad names
// *****************************************************************
// Rev: 17 (Eagle 14.16r1) - 2006-11-09 alf@cadsoft.de
// Delete Lines with Textstring extendet to EXACT / INCLUDE
// *****************************************************************
// Rev: 18 (Eagle 14.16r1) - 2006-12-05 alf@cadsoft.de
// Pad-Names to upper case
// on linkage, check by pin-name (VDD, VCC, VSS, VDD) if the pin really power-pin
// Set direction on all pins of a group of pins in a text-block
// Generate a new symbol!
// If more es 160 pins used, placed the pins as stripes by max (64) pins.
// This make no large symbol if too much pins in device.
// *****************************************************************
// Rev: 19 (Eagle 4.16r2) - 2007-01-10 alf@cadsoft.de
// Start argument "edit-no-description" to switch of red marker in desciption;
// *****************************************************************
// Rev: 20 (Eagle 4.16r2) - 2007-10-15 alf@cadsoft.de
// Button: SortPin (List)
// *****************************************************************
// Rev: 21 (Eagle 4.16r2) - 2008-04-02 alf@cadsoft.de
// Button: Delete Column in Text field
// Button: Delete double pad number in pin-pad-direction list if copy
// text from a document like pdf ...
// *****************************************************************
// Rev: 22 (Eagle 5.0) - 2008-05-20 alf@cadsoft.de
// [Save text as] [Load Text] in Text-Menu
// Rev: 23 (Eagle 5.0) - 2008-06-16 Texas BSDL files are use UPPER-CASE for "PORT"
// Rev: 24 (Eagle 5.0) - 2008-06-19 no check for PIN-coordinates if not symbol generated
// Rev: 25 (Eagle 5.0) - 2008-07-03 numbering pins, set Pin-Direction
// *****************************************************************
// Rev: 26 (Eagle 5.3) - 2008-11-07 Text-Options [Rename PAD]
// Check pin list with pad names if package generated with option Package
// Generate Device-Descriptin also by Text-Option
// New changeable parameter GRID for Package generation,
// if measurements in data sheet in inch, mil, mm.
// remember last bsdl-file path
//
// Rev: 27 (Eagle 5.3) - 2008-12-03 alf@cadsoft.de
// Option for Padname use as in list, or generate by counter
// *****************************************************************
// Rev: 28 (Eagle 5.4) - 2009-02-18 alf@cadsoft.de
// check if list sorted by pad name, to generate correct symbol
// by ascending pad namnes.
// - correct edit option delte x th. line
// *****************************************************************
// Rev: 29 (Eagle 5.4.3) - 2009-03-09 alf@cadsoft.de
// no pad sorting if used bsdl file to generate symbol
//
// Rev: 30 (Eagle 5.6.1) - 2009-10-12 alf@cadsoft.de
// check if exist package definition in bsdl file
//
// Rev: 31 (Eagle 5.6.1) - 2009-10-16 alf@cadsoft.de
// generate only BGAs without file
//
// Rev: 32 (Eagle 5.6.1) - 2009-11-12 alf@cadsoft.de
// change character ';' ',' to '_' in parse function
//
//
string Revision = "Rev. 32";
string HelpDE = "<qt><nobr>Dieses ULP unterstützt die Generierung von Symbolen, Devices und Packages.<br>" +
"Eine <b>BSDL</b>-Datei (<i>Boundary Scan Description Language</i> .bsdl) wird automatisch geparsed.<br>" +
"<b>Pin-Direction:</b> Der Bezeichner '<i>linkage</i>' wird für No-Connects (NC), Power (VCC), oder Ground (GND) benutzt, wobei anhand der BSDL-Daten <br>"+
"nicht unterschieden werden kann ob es sich um einen NC oder PWR Pin handelt.<br>"+
"In einigen Fällen kann es vorkommen das dadurch Signalpins die Direction PWR erhalten, die man manuell im Symbol-Editor ändern muß.<p>"+
"Bei Text-Dateien wird über die Anzahl der Trennzeichen der <font color=blue><i>word separator</i></font> ermittelt und voreingestellt.<p>" +
"Um Text-Dateien (<font color=brown face=times>Tabellen</font>) zu bearbeiten, gibt es folgende Möglichkeiten:<br>" +
"<ul>" +
"<li> <b>Split</b> with <font color=blue><i>word separator</i></font>: Damit wird im Text an der Stelle an der sich ein <i>nicht</i> druckbares Zeichen befindet ein NewLine eingefügt." +
"<li> Split with <b>Character</b>: An der Stelle im Text an der sich dieses <i>druckbare</i> Zeichen befindet, wird ein NewLine eingefügt." +
"<li> <b>Merge</b>: Es werden, entsprechend dem angegebenen Wert, so viele Zeilen zu einer Zeile zusammengefügt.<br>" +
"Als Trennzeichen zwischen den Wörtern wird der gewählte <font color=blue><i>word separator</i></font> benutzt." +
"<li> <b>Replace</b> character string .. with .. : Zeichenketten im Text, die exakt der angegebenen Definition entsprechen, werden ausgetauscht." +
"<li> <b>Delete</b> lines with text: Zeilen, die exakt den angegebenen Text enthalten, werden entfernt.<br>" +
"<li> <b>Delete</b> every x th line [x], Start at line [n] - Löscht jede X-te Zeile ab der n-ten Zeile im Text.<br>" +
"<li> <b>Delete</b> empty lines: Zeilen, die leer sind bzw. nur nicht druckbare Zeichen enthalten, werden entfernt."+
"<li> " +
"<li><b>Parse</b> übersetzt den Text (Tabelle) in die Pin-Pad-Direction-Tabelle.<br>" +
"<li><b>Copy</b> kopiert die <font color=brown face=times>Tabelle</font> wieder in den Text(-Editor).<br>" +
" Als Trennzeichen zwischen den Wörtern wird der gewählte <font color=blue><i>word separator</i></font> benutzt.<br>" +
"<li><b>Swap Pin-Pad</b> tauscht in der Liste die Pin-Pad-Spalten.<br>" +
"<li><b>Sort</b> sortiert die Liste nach Pad-Namen.<p>" +
"</ul>" +
"Durch Anwenden der einzelnen Möglichkeiten kann ein beliebiger Text zu einer brauchbaren Tabelle umgestaltet werden.<br>" +
"Es ist auch möglich einen Text aus der Zwischenablage einzufügen." +
"<p>" +
"Bei Text-Dateien kann ein Package aus der vorhandenen Use-Liste der geladenen LBR gewählt, oder über Package automatisch generiert werden.<br>" +
"Bei BSDL-Dateien (.bsdl) kann ebenfalls ein Package automatisch generiert werden.<br>" +
"Es wird überprüft ob im benutzten Package genügend Pads vorhanden sind um jeden Symbol-Pin zu verbinden.<br>" +
"<p>" +
"<b>BGA</b>-Package generieren (BSDL): Es wird davon ausgegangen, daß das Gehäuse symmetrisch aufgebaut ist.<br>" +
" - Package Width: Die Gehäuseaussenmaße (Kunststoffkörper).<br>" +
" - PAD Grid: Der Abstand zwischen den SMD-Pads.<br>" +
" - PAD Diameter: Der Durchmesser der SMD-Pads.<br>" +
" - 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.<br>" +
"Package generieren: Durch Angabe der Parameter in der Karte Package können zweireihige oder vierseitige Packages generiert werden.<br>" +
"Der Start-Parameter <b>edit-no-description</b> verhindert daß in der Description des Device der Hinweis " +
" <font color=\"red\">edit this description</font> eingetragen wird.<p>" +
"<author>Author: librarian@cadsoft.de</author>";
"</nobr></qt>";
string HelpEN = "<qt><nobr>This ULP supports the generation of Symbols, Devices, and Packages.<br>" +
"A <b>BSDL</b> (<i>Boundary Scan Description Language</i>) file will be parsed automatically<br>" +
"PIN-Direction: In addition to in, out, and inout, a pin can be identified as type linkage.<br>"+
"This is used for no-connects (NC), power (VCC), or ground (GND).<p>"+
"The number of separators in the text file determins and presets the <font color=blue><i>word separator</i></font>.<p>" +
"There are the following possibilities to edit text files (<font color=brown face=times>spreadsheets</font>):<br>" +
"<ul>" +
"<li> <b>Split</b> with <font color=blue><i>word separator</i></font>: Insert NewLine at the position of a <i>non-printable</i> character." +
"<li> Split with <b>Character</b>: Insert NewLine in the text at the position of the given <i>printable</i> character." +
"<li> <b>Merge</b>: Joins the given number of lines to one common line.<br>" +
"The given <font color=blue><i>word separator</i></font> is used as separator between words." +
"<li> <b>Replace</b> character string with: For replacing the given string." +
"<li> <b>Delete</b> lines with text: For deleting lines that contain exactly the given text.<br>" +
"<li> <b>Delete</b> every x th line [x], Start at line [n]: Deletes every x th line, beginning with line number n.<br>" +
"<li> <b> Delete</b> empty lines: For deleting lines that do not contain characters or contain non-printable characters only.<br>" +
"<p>" +
"<li> <b>Parse</b>: Transfers the text (spreadsheet) into the Pin-Pad-Direction spreadsheet." +
"<li> <b>Copy</b>: Copies the <font color=brown face=times>spreadsheet</font> into the text editor again. The given <font color=blue><i>word separator</i></font> will be used between words." +
"<li> <b>Swap Pin-Pad</b>: Exchanges the pin and pad coloumn." +
"<li> <b>Sort</b>: The list will be sorted by pad names." +
"</ul>" +
"These tools allow to make a usable spreadsheet from any text." +
"It is also possible to insert text from the operating sytem's clipboard.<br>" +
"If you are working with text files you have to choose an already existing package from the currently loaded library or use Package.<br>" +
"It is also possible to generate a new package from a BSDL file (*.bsdl).<br>" +
"First the ULP will check if there are sufficient pads for the pins of the symbol.<br>" +
"<p>" +
"Generate a package (BSDL files only): The package is assumed to be designed symmetrically.<br>" +
" - Package width: The dimension of the (plastic) case .<br>" +
" - PAD grid: The distance between the smds.<br>" +
" - PAD diameter: The diameter of the smds." +
" <p>" +
"<author>Author: librarian@cadsoft.de</author>";
"</nobr></qt>";
string Help;
if (language() == "de") Help = HelpDE;
else Help = HelpEN;
string editMode = " <font color=\"red\">edit this description</font>";
string infile, Source_file = "DESCRIPTION '';\n";
string symbol_file, symbol_name;
string device_file, device_name;
string packagefile;
string package_name;
string pac_variant_name = "";
string packages[];
int n_packages = 0;
int package_selected = 0;
real package_wire_width = 0.1016; // to create a new package from BSDL file
real pac_width = 17.0; // to create a quad package from BSDL file
real textsize = 1.27;
real grid_val = 1.0; // for BallGridArea packages
real SMD_diameter = 0.5; // for BallGridArea packages
real MaskRestring = 0.0; // for BallGridArea packages
real CreamDiameter = 0.0; // for BallGridArea packages 2006-06-09
string genpac_grid = "MM"; // 2008-11-07 default grid to generate package, can change in menu to mil, inch, mic.
int smd_pad = 0; // use SMD or PAD for generate Package 2005-12-01
// PAD_SHAPE_SQUARE, PAD_SHAPE_ROUND, PAD_SHAPE_OCTAGON, PAD_SHAPE_LONG, PAD_SHAPE_OFFSET
string PadShape[] = { "SQUARE", "ROUND", "OCTAGON" };
int pad_shape = PAD_SHAPE_ROUND;
string packinfomess = "<img src=\"make_package_meass_smdinfo.bmp\">";
// new Menu Paramter to auto generate
int pad_layout;
int Pad_Count = 1; // the pads of package
int cnt_side = 0; // calculated pads on one side of package
real xA_pac = 14.0; // width of the metall pins
real yA_pac = 14.0; // width of the metall pins for quad package
real xD_pac = 12.0; // width of the plastic package in x
real yD_pac = 12.0; // width of the plastic package in y
real basic_pad_grid = 0.65; // the Basic grid Pad to Pad
real pad_width = 0.35; // the width of solder pin
real pad_stand_out = 0.5; // stand out the pad over the metall pin
real ypad_length = 0.4; // the pad width
real xpad_length = 0.9; // the pad length
real mark_length = 0.6; // length of corner edge to mark pad 1
real roundness_restring = 0; // the SMD roundness for QFP/LCC/DualInline
string round_restring = "Roundness %";
int packageparameter_accept; // if all parameter Ok for QFP/LCC/DualInline
int BGAparameter_accept; // if BGA parameter accept for generate package
string paccmd; // the script to generate qfp/lcc/Dual-Inline
int pin_map_cnt = 0; // count the maps in the file
string pin_map_name; // the name of actual pin map
char w_separator[] = { ' ' , '\b', '\f',
'\n', '\r', '\t',
'\v', 0 };
string separator[] = { "SPACE", "Backspace", "Form Feed",
"New Line", "Carriage Return", "Horizontal tab",
"Vertical tab", "" };
int select_separ = 0;
char Word_separator = w_separator[select_separ];
string String_separator;
string Vector_name[];
int sVector[], eVector[];
int cnt_vector;
string up_down;
string text;
string lines[];
int n_lines;
numeric string pin_names[];
int n_pin_names = 0;
numeric string pad_names[];
int n_pad_names = 0;
int use_pad_names = 0;
enum { useNONE, useBGA, usePACwithPrefix } // for use Padnames to generate Device
string pad_prefix;
string old_pad_prefix;
string checkPadname = "";
numeric string pins_pads_direc[];
numeric string pins[];
numeric string pads[];
string pin_direc[];
int suffix[];
int suffix_cnt, suffix_point;
int suffix_s, suffix_e;
int n_pins = 0;
int n_pads = 0;
int maxPinCnt = 100;
int maxStripeCnt = 64; // maximum of pins on a stripe in symbol
string pinCntInfo = " "; // Info if more as maxPinCnt pins used in one Symbol 2006-12-05
// extend this list to set pin direction on power by linkage 2006-12-05
string PowerName[] = {
"GND",
"VCC",
"VDD",
"VSS",
"VEE",
"+5V",
"-5V",
"" // the last must be empty ""
} ;
enum { k_single, k_dual, k_dual2, k_quad , k_stripe };
int pin_layout = k_dual;
int is_bsdl = 0;
int pars_mode;
int breacked_status = 0;
enum { mode_null, mode_port, mode_map };
string bsdl_map_pin; // the actual map pin name
// more as one pins can named as the same
string bsdl_pin_name[];
string bsdl_pin_dir[];
int cnt_bsdl_port;
string parsed_pins = " ";
string bsdl_package_name;
int make_Package; // generate Package by generated script
char port_separator = ':';
char PIN_MAP_separator = ':';
string tinfo = " ";
string MakePacInfo = " ";
int select = 0;
int sorting = 0; // view list
int index[];
string used_pad_number[]; // 2008-11-07
enum { e_symbol, bga_pac, e_pac }; // editor type to check max value of grid
string rememberBSDLpath; // 2008-11-07
string rememberLastPathFile = "~remember-make-bsdl~.mem";
// 2009-10-16
string bga_pad_name[] = { "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "T", "U", "V", "W", "Y", "" };
int cntBGApadX = 44;
int cntBGApadY = 44;
int only_generate_bga = 0;
/****************************************
########## Functions ###########
****************************************/
// 2008-11-07 check if exist package, but do not generate
int check_exist_pac(string pacname) {
int exist = 0;
library(L) {
L.packages(PAC) {
if (PAC.name == pacname) return 1;
}
}
return 0;
}
int check_Coordinate(string name, real x, real y, string grid_unit, int edit_type) { // 2008-11-07 new, grid unit, editor type
string s;
real maxminxy;
if (grid_unit == "MM") maxminxy = u2mm(8382000); // 2008-11-07 check max x-y by used grid
else if (grid_unit == "INCH") maxminxy = u2inch(8382000);
else if (grid_unit == "MIL") maxminxy = u2mil(8382000);
else if (grid_unit == "MIC") maxminxy = u2mic(8382000);
else {
if (edit_type == bga_pac) dlgMessageBox("Check grid parameter in BGA menu!", "OK");
else if (edit_type == e_pac) dlgMessageBox("Check grid parameter in Package menu!", "OK");
return -1;
}
if (x > maxminxy || x < -maxminxy ) {
sprintf(s, "<nobr>Too much pins to generate symbol in X<br>Coordinate (%.4f) %s out of range %.4f %s<p>", x, grid_unit, maxminxy, grid_unit);
}
if (y > maxminxy || y < -maxminxy) {
sprintf(s, "<nobr>Too much pins to generate symbol in Y<br>Coordinate (%.4f) %s out of range %.4f %s<p>", y, grid_unit, maxminxy, grid_unit);
}
if (s) {
if (edit_type == e_symbol) s += "Check <b>Symbol Pin Layout:</b> Single | Dual | Quad before exiting this ULP</nobr>";
else if (edit_type == bga_pac) s += "Check pad names in BSDL file<br>" + infile + "<br> and/or measures in BGA menu.";
else if (edit_type == e_pac) s += "Check pad names <br>" + infile + "<br> 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, "<nobr>%d words replaced</nobr>", ct);
dlgRedisplay();
return;
}
void gen_viewlist(int cnt) {
status ("generate list"); // 2008-11-07 display working
for (int i = 0; i < cnt; i++) {
sprintf( pins_pads_direc[i], "%s\t%s\t%s", pin_names[i], pad_names[i], pin_direc[i]);
}
pins_pads_direc[i] = ""; // 2008-04-02
return;
}
string clear_textline(string line, char c) {
int pos;
do {
pos = strchr(line, c);
if (pos >= 0) line[pos] = '_'; // 2009-11-12 alf@cadsoft.de
} while (pos >= 0);
return line;
}
void filter_pin_pad( int use_pad_names) {
for (int d = 0; d <= n_pins; d++) {
pins_pads_direc[d] = "";
pin_names[d] = "";
pad_names[d] = "";
pins[d] = "";
pads[d] = "";
pin_direc[d] = "";
suffix[d] = 0;
}
n_pins = 0;
for (int i = 0; i < n_lines; i++) {
lines[i] = clear_textline(lines[i], ';');
string pin_name = cleanName(lines[i]);
string pad_name = "";
int n;
string items[];
n = strsplit(items, lines[i], Word_separator);
if (n > 0) {
pin_name = cleanName(items[0]);
if (use_pad_names = useBGA) { // ## useNONE, useBGA, usePACwithPrefix, isePACwithoutPrefix ##
pad_name = cleanName(items[1]);
}
if (strlen(pin_name) > 0) {
pins[n_pins] = pin_name;
if (use_pad_names) pads[n_pads++] = pad_name;
if (n > 2) pin_direc[n_pins] = items[2]; // 2008-04-02
pin_names[n_pins] = pin_name;
pad_names[n_pins] = pad_name;
n_pins++;
}
}
}
pins[n_pins] = "";
pads[n_pins] = "";
pin_names[n_pins] = "";
pad_names[n_pins] = "";
pins_pads_direc[n_pins] = "";
pin_direc[n_pins] = "";
pin_direc[n_pins] = "";
suffix[n_pins] = 0;
gen_viewlist(n_pins);
return;
}
void filter_text( int use_pad_names) {
n_lines = strsplit(lines, text, '\n');
filter_pin_pad( use_pad_names);
sprintf( parsed_pins, "%d pins parsed", n_pins); // 2008-11-07
Pad_Count = n_pins; // set pin counter for package option on text
return;
}
// ** scratch line after position n **
string scratch(string p, char c, int n) {
int pos = strchr(p, c, n);
if (pos > 0) return strsub(p, 0, pos);
else return p;
}
/* ******************************************************
Analog-Device use "linkage" also for signal pins!!
Example:
CLKIN: linkage bit;
XTAL: linkage bit;
VROUT: linkage bit_vector(0 to 1));
*******************************************************
http://www.actel.com/documents/BSDLformat.pdf
In addition to in, out, and inout, a pin can be identified as type linkage.
This is used for no-connects (NC), power (VCC), or ground (GND).
******************************************************** */
string pin_direction( string bsdldir) {
string pin_dir;
bsdldir = scratch( bsdldir, ' ', 1); // for Xilinx BSM-Files 14.09.2004 alf
bsdldir = scratch( bsdldir, ';', 1);
if (bsdldir == "inout") pin_dir = "I/O";
else if (bsdldir == "out") pin_dir = "OUT";
else if (bsdldir == "in") pin_dir = "IN";
else if (bsdldir == "linkage") pin_dir = "PWR";
else if (bsdldir == "buffer") pin_dir = "HIZ";
else {
bsdldir = scratch( bsdldir, '(', 0);
}
if (bsdldir == "linkage bit_vector") pin_dir = "PWR";
// ** 09.09.2004 place a ';' in Xilinx BSD-Files **
// ** to separate " linkage bit_vector" ! **
return pin_dir;
}
string get_dir( string name) { // ** direction of pin **
for (int i = 0; i < cnt_bsdl_port; i++) {
if (bsdl_pin_name[i] == name) {
return bsdl_pin_dir[i];
break;
}
}
return "";
}
string getVector(string v) { // ** count up or down **
string Vname, vs[];
int pos;
pos = strsplit(vs, v, ':');
pos = strsplit(vs, vs[0], ' ');
for (int n = pos; pos; n--) {
if (vs[n]) break;
}
if (vs[n][0] == '(') vs[n] = strsub(vs[n], 1);
return vs[n];
}
void parse_bit_vector(string l) {
/* EXAMPLE **************************************************
XILINX-BSM-File
VCCAUX: linkage bit_vector; (1 to 16);
VCCINT: linkage bit_vector; (1 to 16);
INTEL-BSDL-File
port (pci_ad : inout bit_vector(31 downto 0);
pci_cbe_n : inout bit_vector(3 downto 0);
** ^ ^ **
** counter direction up = to / down = downto. **
********************************************************** */
int pos = strstr(l, "bit_vector", 0);
if (pos > 0) {
Vector_name[cnt_vector] = getVector(l);
status(Vector_name[cnt_vector]); // 2008-11-07 display working
string s, v, vs[];
s = strsub(l, pos);
int n = strsplit(vs, s, '(' ); // cut up to (
s = vs[1];
n = strsplit(vs, s, ')' ); // cut )
s = vs[0];
n = strsplit(vs, s, ' ' );
sVector[cnt_vector] = strtol(vs[0]);
eVector[cnt_vector] = strtol(vs[2]);
up_down = vs[1];
cnt_vector++;
}
return;
}
// search & count breackeds for parse end 05.10.2005
void brackeds(string l) {
string br[];
int open_breacked = strsplit(br, l, '(');
int close_breacked = strsplit(br, l, ')');
breacked_status += (open_breacked - close_breacked);
return;
}
// ** BSDL parser **
void pars_port(string l) {
status("parse port");
brackeds(l);
if (!breacked_status) { // end of port list 2005-10-05
pars_mode = mode_null;
}
string k[];
// if more as 1 port in line, it's a group of ports in line! 2006-12-05
int cntk = strsplit(k, l, ',');
for (int nk = 0; nk < cntk; nk++) {
string p[];
int n = strsplit(p, k[nk], port_separator); // ':'
if (n > 1) {
bsdl_pin_name[cnt_bsdl_port] = trimString(p[0]);
bsdl_pin_dir[cnt_bsdl_port] = pin_direction(trimString(p[1]));
if (bsdl_pin_dir[cnt_bsdl_port] == "PWR") { // check if realy a power pin by name 2006-12-05
int cntpwr = 0, np = 0;
do {
cntpwr += strstr(bsdl_pin_name[cnt_bsdl_port], PowerName[np])+1; // to check more names, extend the line PowerName[]...
if (cntpwr) break;
np++;
} while (PowerName[np]);
if (!cntpwr) bsdl_pin_dir[cnt_bsdl_port] = "PAS"; // no powerpin 2006-12-05
}
parse_bit_vector(l);
cnt_bsdl_port++;
}
}
return;
}
int get_suffix(string vector) {
int n;
for (n = cnt_vector; n >= 0; n--) {
if (vector == Vector_name[n]) break;
}
return n;
}
void pars_map(string l) {
status("parse maping");
if (strstr(l, ";") >= 0 ) { // semikolon marks end of map list
pars_mode = mode_null; // set parse mode
}
l = clear_line(l); // replace '"' and '(' and ')' with space, and replace ';' with ','
l = cleanWhitespace(l);
string lq[];
int nlq = strsplit(lq, l, ','); // 2006-07-06 more as 1 Pin-Pad-Definition in Xilinx-BSDL files
// Example : xc2c32a_cp56.bsd
// constant CP56 : PIN_MAP_STRING :=
// "TCK : K10, TDI : J10, TDO : A6, TMS : K9, " &
for (int nq = 0; nq <= nlq; nq++) {
l = lq[nq];
string p[];
string pad_map;
int n = strsplit(p, l, PIN_MAP_separator); // ':'
if (n > 1) { // pin name
string ps[];
int nn = strsplit(ps, trimString(p[0]), ' ');
bsdl_map_pin = ps[0]; // a new pin name
pad_map = p[1]; // pad name(s)
status(pad_map); // 2008-11-07 display working
suffix_point = get_suffix(bsdl_map_pin);
if (suffix_point < 0) {
suffix_cnt = -1; // set counter negativ -1
}
else {
suffix_s = sVector[suffix_point];
suffix_e = eVector[suffix_point];
suffix_cnt = suffix_s;
}
}
else { // only pad names
pad_map = p[0];
}
pad_map = spaceCharacter(pad_map, ',');
pad_map = cleanWhitespace(pad_map);
n = strsplit(p, pad_map, ' ');
for (int i = 0; i <= n; i++) {
if (p[i]) { // ** 2005-01-10
// line can start with ", ..."
// line can end with ...,"
pins[n_pins] = bsdl_map_pin;
pads[n_pins] = strupr(trimString(p[i])); // upper case ** 2006-12-05
suffix[n_pins] = suffix_cnt;
if (suffix_cnt >= 0) {
if (up_down == "to") suffix_cnt++;
else if (up_down == "downto") suffix_cnt--;
}
n_pins++;
}
}
pins[n_pins] = ""; // clear +1
pads[n_pins] = "";
pin_names[n_pins] = "";
pad_names[n_pins] = "";
suffix[n_pins] = 0;
}
return;
}
string get_devName(string l) {
l = cleanWhitespace(l);
string s[];
int n = strsplit(s, l, ' ');
if (n > 1) return strupr(s[1]);
return "--";
}
string get_pacName(string l) {
string s[];
int n = strsplit(s, l, '"');
if (n > 1) return strupr(s[1]);
return "";
}
string get_pin_map_name(string l) {
l = cleanWhitespace(l);
string s[];
int n = strsplit(s, l, ' ');
n = strsplit(s, s[1], ':');
return s[0];
}
/* EXAMPLE ************************************************
entity IXP4XX is
generic(PHYSICAL_PIN_MAP : string:= "BGA");
port (pci_ad : inout bit_vector(31 downto 0);
pci_cbe_n : inout bit_vector(3 downto 0);
pci_par : inout bit;
pci_frame_n : inout bit;
....
...
..
constant BGA:PIN_MAP_STRING :=
"pci_ad : (D3, C2, J6, B1, A1, C1, D1, G3,"&
" E1, J4, G1, F1, K5, H2, K3, H1,"&
" N5, P2, P3, P5, N1, R1, R3, U1,"&
" U4, T1, V1, R5, V3, T4, W1, U3),"&
"pci_cbe_n : (H4, K1, M1, P1),"&
"pci_par : M2,"&
******************************************************** */
void filter_bsdl(void) {
n_lines = strsplit(lines, text, '\n');
int n;
/** counter and strings reset **/
suffix_cnt = 0;
pars_mode = mode_null;
cnt_bsdl_port = 0;
pin_map_cnt = 0; // use multiple PIN_MAP_STRING: in BSDL
n_pins = 0;
package_name = "";
package_selected = 0;
for ( n = 0; n < n_lines; n++) {
string line = lines[n];
if (strstr(line, "--") == 0); // comment
else {
switch(pars_mode) {
case mode_port: /*** parse port lines pin-names and function ***/
pars_port(trimString(line)); // 2005-01-10 trim spaces on left side of string
break;
case mode_map: /*** parse pad-name ***/
pars_map(line);
break;
default : int pos = strstr(strlwr(line), "port"); // 2008-06-16 Texas BSDL files are UPPER-CASE for "PORT"
if (pos >= 0) {
brackeds(line);
pars_mode = mode_port;
pos = strstr(line, "(", pos);
string p = strsub(line, pos+1);
pars_port(trimString(p));
}
else if (strstr(line, "constant") >= 0 && strstr(line, "PIN_MAP_STRING") > 8) {
if (!pin_map_cnt) {
package_name = strupr(get_pin_map_name(line));
pin_map_cnt++;
pars_mode = mode_map;
package_selected = 0;
}
else {
string next_pin_map = get_pin_map_name(line);
pin_map_cnt++;
if (dlgMessageBox("<nobr>found next MAP list <b>" + next_pin_map + "</b> (Package), last Map list <b>" + package_name + "</b> (Package)<p>Use MAP?</nobr>", next_pin_map, package_name) != 0) ;
else {
package_name = strupr(next_pin_map);
pars_mode = mode_map;
suffix_cnt = 0; // reset counter an arrays 06.10.2005
n_pins = 0; // reset pin list counter
}
}
}
if (strstr(line, "entity") == 0) {
device_name = get_devName(line); // 23.11.2004 alf
}
if (strstr(line, "generic") >= 0) {
package_name = strupr(get_pacName(line)); // 23.11.2004 alf
package_selected = 0;
}
break;
}
}
}
status ("generate direction"); // 2008-11-07 display working
for ( n = 0; n < n_pins; n++) {
pin_direc[n] = get_dir( pins[n]);
if (suffix[n] >= 0) {
if (pin_direc[n] == "PWR") {
sprintf( pin_names[n], "%s@%d", pins[n], suffix[n]);
}
else {
sprintf( pin_names[n], "%s%d", pins[n], suffix[n]);
}
pins[n] = pin_names[n];
}
else pin_names[n] = pins[n];
pad_names[n] = pads[n];
}
// ** in a text block, only the last line define the direction **
// ** fill down the pindirection in list 2006-12-05 **
for ( n = n_pins - 1; n; n--) {
if (!pin_direc[n-1] && pin_direc[n]) pin_direc[n-1] = pin_direc[n];
}
pins_pads_direc[n_pins] = ""; // make shure the last in the list is empty!
pin_names[n_pins] = "";
pad_names[n_pins] = "";
Pad_Count = n_pins; // 2008-11-07 set pad counter
sprintf( parsed_pins, "%d pins parsed", n_pins);
dlgRedisplay();
if (n_pins > 160) { // 2008-11-07
sprintf(pinCntInfo, "<font color=\"red\">Too many pins for a small symbol.</font> Tip: Generate symbol with stripes of ma<u>x</u> pins in line."); // 2006-12-05
pin_layout = k_stripe;
}
else if (n_pins > maxPinCnt) {
sprintf(pinCntInfo, "<font color=\"red\">Too many pins for a small symbol.</font> Generate symbol with four sides.");
pin_layout = k_quad; // 2008-11-07
}
sprintf( bsdl_package_name, "<nobr>Used package in BSDL file: <font color=blue>%s</font></nobr>", package_name );
gen_viewlist(n_pins);
return;
}
void check_separator(void) {
string tx[];
int scnt = 0;
int n = -1;
do {
n++;
int i = strsplit(tx, text, w_separator[n]);
if (scnt < i) {
scnt = i;
select_separ = n;
Word_separator = w_separator[select_separ];
sprintf(String_separator, "%c", Word_separator);
}
} while(w_separator[n]);
return;
}
// is in Text "BSDL" then mark Text as BSDL 2005-10-18
int scan_isbsdl(void) {
int bsdl = 0;
bsdl = strstr(text, "BSDL");
if (bsdl > 0) return 1;
return 0;
}
void readText( string file) {
string base_file = filename(file);
string base_name = cleanName(strsub(filename(file), 0, strrchr(base_file, '.')));
symbol_name = base_name;
device_name = base_name;
// reset all counters
for (int d = 0; d <= n_pins; d++) {
pins_pads_direc[d] = "";
pin_names[d] = "";
pad_names[d] = "";
pins[d] = "";
pads[d] = "";
pin_direc[d] = "";
suffix[d] = 0;
}
n_pins = 0;
n_pads = 0;
n_pin_names = 0;
n_pad_names = 0;
package_name = "";
int n = fileread(text, file);
status("parse ..."); // 2008-11-07 display, im working
is_bsdl = scan_isbsdl();
string f = strlwr(fileext(file));
if (f == ".bsm" || f == ".bsd" || f == ".bsdl" || is_bsdl) {
// ** clear tabulator in text **
tinfo = "<nobr><font color=\"blue\">Parsing BSDL file, please wait!</font></nobr>";
parsed_pins = "<nobr><font color=\"darkgreen\">Please wait!</font></nobr>";
dlgRedisplay();
int i;
do {
i = strchr(text, '\t');
if(i > 0) {
text[i] = ' ';
}
} while (i > 0);
use_pad_names = useBGA;
pad_prefix = "";
filter_bsdl(); // file parse
is_bsdl = 1;
}
if (!is_bsdl) check_separator();
sprintf(tinfo, "<nobr>[text length %d character]</nobr>", strlen(text) );
dlgRedisplay();
return;
}
string split_row_column(string p, int type) {
int n;
for (n = 0; n < strlen(p); n++) {
if (p[n] > '@');
else break;
}
if (type) return strsub(p, n);
return strsub(p, 0, n);
}
// *** BGAs can use 2 Alpha-Character for Pad-Name ***
void padsort(void) {
int n;
for (n = 0; n < n_pins; n++) {
if(isalpha(pad_names[n][1])) {
pad_names[n] = "~" + pad_names[n];
}
}
sort(n_pins, index, pad_names);
for (n = 0; n < n_pins; n++) {
if(pad_names[n][0] == '~') {
pad_names[n] = strsub(pad_names[n], 1);
}
}
}
void makePackage(string file) {
real maxcolumn;
packagefile = filesetext(file, "~package.scr");
output(packagefile, "wtD") {
if(packageparameter_accept) printf("%s", paccmd); /** generate QFP/LCC/DUAL-Line **/
else if (BGAparameter_accept) { /** generate BGA **/
printf("EDIT %s.PAC;\n", package_name);
printf("GRID %s %.4f ON;\n", genpac_grid, grid_val/2); // 2008-11-07 set actual grid to generate package
printf("SET WIRE_BEND 2;\n");
printf("CHANGE ROUNDNESS 100;\n");
printf("CHANGE LAYER 1;\n");
printf("CHANGE SMD %.4f %.4f;\n", SMD_diameter, SMD_diameter);
padsort();
int cntrow, column, cntcolumn; // Zeile/Spalte
string row_name, last_name;
for (int n = n_pins-1; n >= 0; n--) {
row_name = split_row_column(pad_names[index[n]], 0);
column = strtol(split_row_column(pad_names[index[n]], 1));
if(maxcolumn < column) maxcolumn = column;
if (last_name != row_name) {
cntrow++;
last_name = row_name;
}
if (check_Coordinate(pad_names[index[n]], grid_val*column, grid_val*cntrow, genpac_grid, bga_pac)) exit(0); // 2008-11-07 grid from bga
printf("CHANGE LAYER 1;\n");
printf("SMD NOSTOP NOCREAM '%s' (%.4f %.4f);\n", pad_names[index[n]], grid_val*column, grid_val*cntrow );
printf("CHANGE LAYER 29;\n"); // tStop
printf("CIRCLE 0 (%.4f %.4f) (%.4f %.4f);\n", grid_val*column, grid_val*cntrow, grid_val*column + SMD_diameter/2+MaskRestring, grid_val*cntrow);
if (CreamDiameter) {
printf("CHANGE LAYER 31;\n"); // tCream
printf("CIRCLE 0 (%.4f %.4f) (%.4f %.4f);\n", grid_val*column, grid_val*cntrow, grid_val*column + CreamDiameter/2, grid_val*cntrow);
}
}
printf("GROUP (%.4f %.4f) (%.4f %.4f) (%.4f %.4f) (%.4f %.4f) (>%.4f %.4f);\n",
-1.0 * grid_val, -1.0 * grid_val,
grid_val * (maxcolumn+1), -1.0 * grid_val,
grid_val * (maxcolumn+1), grid_val * (cntrow+1),
-1.0 * grid_val, grid_val * (cntrow+1),
-1.0 * grid_val, -1.0 * grid_val );
real centerx, centery;
centerx = (grid_val * (maxcolumn+1)) / 2;
centery = (grid_val * (cntrow+1)) / 2;
printf("MOVE (>%.4f %.4f) (0 0);\n", centerx, centery);
printf("SET WIRE_BEND 0;\n");
printf("CHANGE LAYER 21;\n");
printf("WIRE .2032 (%.4f %.4f) (%.4f %.4f) (%.4f %.4f);\n",
-pac_width /2 + package_wire_width, -pac_width /2 + package_wire_width,
pac_width /2 - package_wire_width, pac_width /2 - package_wire_width,
-pac_width /2 + package_wire_width, -pac_width /2 + package_wire_width);
// *** mark edge on pin 1 ***
printf("SET WIRE_BEND 2;\n");
printf("WIRE .2032 (%.4f %.4f) (%.4f %.4f);\n",
-pac_width /2 + package_wire_width, pac_width /2 - grid_val,
-pac_width /2 + grid_val, pac_width /2 - package_wire_width);
printf("CHANGE SIZE %.2f;\n", textsize);
printf("CHANGE LAYER 25;\n");
printf("TEXT >NAME (%.4f %.4f);\n",
-pac_width/2, pac_width/2 + textsize*0.5);
printf("CHANGE LAYER 27;\n");
printf("TEXT >VALUE (%.4f %.4f);\n",
-pac_width/2, -pac_width/2 - textsize*1.5);
printf("%s\n", Source_file);
}
}
return;
}
int device_exist(string dev_name) {
library(L) {
L.devicesets(DEV) {
if (DEV.name == dev_name) {
return 1;
}
}
}
return 0;
}
string makeSymbol_Device(string Libfile, int pin_layout, string pac_name, int use_pad_names, string pad_prefix) {
symbol_file = filesetext(Libfile, "~symbol.scr");
device_file = filesetext(Libfile, "~device.scr");
string partlib = "EDIT " + symbol_name + ".sym;\nGRID INCH 0.1;\n";
partlib += "CHANGE LENGTH MIDDLE;\n";
partlib += "CHANGE DIRECTION PAS;\n"; // ** default direction
string devicelib = "EDIT " + device_name + ".dev;\n";
devicelib += "GRID INCH 0.1 ON;\n";
devicelib += "PACKAGE " + pac_name + " '" + pac_variant_name + "';\n";
devicelib += "Technology '';\n";
if (device_exist(device_name)) return "Device " + device_name + "exist!\nPlease use a different name for tis device."; // 2008-11-07 check existing devices and return error
else {
// 2008-11-07 generate always description
sprintf(Source_file, "DESCRIPTION '<b>%s</b>%s<p>\\n\\\nAuto generated by <i>%s %s</i><br>\\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, "<nobr>%d characters changed.</nobr>", cc);
return;
}
string check_space(string s) {
int a;
for (int i = 0; i < strlen(s); i++) {
a = (isgraph(s[i]));
if (a) break;
}
if (a) return s;
else return "";
}
void delete_x_line(int start, int x) {
if (x < 2) {
dlgMessageBox("!The value of the counter must be greater 1", "Ok");
tinfo = "<nobr>It is absurd to delete all lines! Check the value of x. line</nobr>";
return;
}
if (start > 1) start--; // 2009-02-18 counts from zero
string xt[];
int cntst = strsplit(xt, text, '\n');
text = "";
int cdel = 0;
for (int s = start; s < cntst; s+=x) {
xt[s] = "";
}
for (int n = 0; n < cntst; n++) {
if (xt[n]) text += xt[n] + "\n";
else cdel++;
}
text[strlen(text)-1] = 0;
if (x > 2) sprintf(tinfo, "<nobr>%d %d. lines deleted</nobr>", cdel, x);
else sprintf(tinfo, "<nobr>%d second lines deleted</nobr>", cdel);
return;
}
void delete_empty_lines(void) {
if(!text) {
tinfo = "<nobr>List is empty!</nobr>";
return;
}
string st[];
int cntst = strsplit(st, text, '\n');
text = "";
int cc = 0;
for (int n = 0; n < cntst; n++) {
st[n] = check_space(st[n]);
if (st[n]) text += st[n] + "\n";
else cc++;
}
text[strlen(text)-1] = 0;
sprintf(tinfo, "<nobr>%d empty lines deleted</nobr>", cc);
return;
}
void delete_column(int del_column) { // 2008-04-02
if (!text) {
tinfo = "<nobr>List is empty!</nobr>";
return;
}
if (!del_column) {
tinfo = "<nobr>First set the number of column to delete!</nobr>";
return;
}
string lines[];
string columns[];
int cntl = strsplit(lines, text, '\n');
text = "";
for (int n = 0; n < cntl; n++) {
int cntc = strsplit(columns, lines[n], Word_separator);
columns[del_column -1] = "";
lines[n] = "";
for (int c = 0; c < cntc; c++) {
lines[n] += columns[c];
if (c < cntc -1 && columns[c]) lines[n] += " ";
}
text += lines[n] += "\n";
}
return;
}
void sorting_pad(int cnt) {
numeric string sort_pad[], sort_pin[], sort_dir[];
int index[], i;
for (i = 0; i < cnt; i++) {
pins[i] = pads[i];
sort_pin[i] = pin_names[i];
sort_pad[i] = pad_names[i];
sort_dir[i] = pin_direc[i];
}
sort(cnt, index, sort_pad, sort_pin);
for (i = 0; i < cnt; i++) {
pin_names[i] = sort_pin[index[i]];
pad_names[i] = sort_pad[index[i]];
pin_direc[i] = sort_dir[index[i]];
pins[i] = pin_names[i];
pads[i] = pin_names[i];
}
return;
}
void sorting_pin(int cnt) {
numeric string sort_pad[], sort_pin[], sort_dir[];
int index[], i;
for (i = 0; i < cnt; i++) {
pins[i] = pads[i];
sort_pin[i] = pin_names[i];
sort_pad[i] = pad_names[i];
sort_dir[i] = pin_direc[i];
}
sort(cnt, index, sort_pin, sort_pad);
for (i = 0; i < cnt; i++) {
pin_names[i] = sort_pin[index[i]];
pad_names[i] = sort_pad[index[i]];
pin_direc[i] = sort_dir[index[i]];
pins[i] = pin_names[i];
pads[i] = pin_names[i];
}
return;
}
int check_pad_sorting(int cnt, int mkpac) { // 2009-02-18
int sortflagPAD = 0;
int RESULT = 0;
if (!mkpac && use_pad_names == useBGA) sortflagPAD = 1; // option for use existing BGA 2009-03-09
else if (!mkpac && package_name) {
for (int n = 0; n < cnt; n++) {
if (strtol(pad_names[n]) != n+1) {
sortflagPAD++;
string h;
sprintf(h, "Missing Pad number (%d) or sort list by pad number", n+1);
if (dlgMessageBox(h, "OK", "Cancel") != 0) return -1;
}
}
if (sortflagPAD) {
RESULT = dlgDialog("Make PAC/SYM/DEV") {
dlgLabel("To generate a correct symbol by counte pad name, the list must sorted by pad number!");
dlgLabel("Check if Pin/Pad/Direction list sorted by PADs?");
dlgHBoxLayout {
dlgPushButton("Yes/Ignore") dlgAccept();
dlgPushButton("Sort") {
sorting_pad(cnt);
gen_viewlist(cnt);
dlgAccept();
}
dlgPushButton("Cancel") dlgReject();
}
};
}
}
return RESULT;
}
string clear_z(string s) { // delete leading zero
parsed_pins = s;
if (isalpha(s[0]) && isalpha(s[1]) && s[2] == '0') s = strsub(s, 0, 2) + strsub(s, 3);
else if (isalpha(s[0]) && s[1] == '0') s = strsub(s, 0, 1) + strsub(s, 2);
else if (s[0] == '0') s = strsub(s, 1);
return s;
}
void clear_leading_z(int cnt) {
for (int i = 0; i < cnt; i++) {
pad_names[i] = clear_z(pad_names[i]);
}
gen_viewlist(cnt);
parsed_pins = "<nobr>Finsh clear leading zeros</nobr>";
return;
}
int del_double_pad(int cnt) { // 2008-04-02 delete double pad names if parsed from text
sorting_pad(cnt);
string npad = "";
string npin_names[];
string npad_names[];
string npin_direc[];
int newcnt = 0;
for (int i = 0; i < cnt; i++) {
if (npad == pad_names[i]) {
; // is double
}
else {
npad = pad_names[i];
npin_names[newcnt] = pin_names[i];
npad_names[newcnt] = pad_names[i];
npin_direc[newcnt] = pin_direc[i];
newcnt++;
}
}
sprintf(parsed_pins, "<nobr>Finsh delete double (%d) pad name, new count %d</nobr>", cnt-newcnt, newcnt);
for (int n = 0; n < newcnt; n++) {
pin_names[n] = npin_names[n];
pad_names[n] = npad_names[n];
pin_direc[n] = npin_direc[n];
}
cnt = newcnt;
gen_viewlist(cnt);
return cnt;
}
// 2008-11-07 rename pad in parsed list
void rename_pad(int cnt, string search, string replace) {
int cntrenamed = 0;
if (!search) {
dlgMessageBox("First define search string!<br>See option:<br>[ <u>R</u>eplace ] character strin<u>g</u> ..... <u>w</u>ith ....", "OK");
return;
}
if (search == replace) {
dlgMessageBox("Search string = Replace string, please change!<br>See option:<br>[ <u>R</u>eplace ] character strin<u>g</u> .... <u>w</u>ith .....", "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 '<b>%s</b><p>\\n\\\nAuto generated by <i>%s %s</i><br>\\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 = "<img src=\"make_package_meass_pacinfo.bmp\">";
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("<img src=\"make_symbol_single.bmp\">");
dlgCell(1, 3) dlgRadioButton("Dual &1", pin_layout) pinCntInfo = " ";
dlgCell(0, 3) dlgLabel("<img src=\"make_symbol_dual1.bmp\">");
dlgCell(1, 5) dlgRadioButton("Dual &2", pin_layout) pinCntInfo = " ";
dlgCell(0, 5) dlgLabel("<img src=\"make_symbol_dual2.bmp\">");
dlgCell(1, 7) dlgRadioButton("&Quad", pin_layout) pinCntInfo = " ";
dlgCell(0, 7) dlgLabel("<img src=\"make_symbol_quad.bmp\">");
dlgCell(1, 9) dlgRadioButton("Str&ipe", pin_layout) pinCntInfo = "<qt><nobr>Tip: Use <b>split-device-symbol.ulp</b> to generate a Device with multiple small symbols! Read HELP."; // 2006-12-05
dlgCell(0, 9) dlgLabel("<img src=\"make_symbol_stripe.bmp\">");
dlgCell(0, 10) dlgVBoxLayout {
dlgStretch(1);
dlgLabel("Ma&x.\nPins\nper\nStripe");
dlgHBoxLayout {
dlgIntEdit(maxStripeCnt);
dlgStretch(1);
}
}
}
dlgStretch(1);
dlgLabel(pinCntInfo, 1);
dlgStretch(1);
}
dlgStretch(1);
}
dlgStretch(1);
dlgHBoxLayout { dlgSpacing(8); dlgLabel(MakePacInfo, 1); } // info what package parameter in use
dlgStretch(1);
dlgHBoxLayout {
dlgSpacing(8);
dlgPushButton("Ok") {
string error = "";
string Libfile;
if (!Libfile) {
library(L) Libfile = L.name;
}
if (make_Symbol) { // 2008-11-07
if (check_pad_sorting(n_pins, make_Package)) { // 2009-02-18 check if pads sorted ascending
error = "Cancelt by check pad number!";
}
if (check_exist_sym(strupr(symbol_name))) {
error = "Check symbol name, symbol exist!";
}
if (!error) error = makeSymbol_Device(Libfile, pin_layout, package_name, use_pad_names, pad_prefix);
if (!error) {
int sympincount = getSymbolPinCount(strupr(symbol_name));
if (sympincount >= 0) { // ** symbol exist, do not change or add pins **
string s; sprintf(s, "Symbol %s has %d pins", symbol_name, sympincount);
error = "Symbol " + symbol_name + " exists, use another name for this new symbol!";
// make_Symbol = 0; // 2008-11-07 reset/set this option by hand
}
}
}
else {
if (!only_generate_bga) { // 2009-10-19
if (!check_exist_sym(strupr(symbol_name))) error = "Check symbol, symbol NOT exist!";
}
}
if (make_Package) { // do not generate package while exist 2008-11-07
if (check_exist_pac(package_name)) make_Package = 0; // reset flag
}
else PadCount = "";
if (make_Device && !error) {
if (!make_Package && package_name) ;
else if (make_Package && BGAparameter_accept || make_Package && packageparameter_accept) ; // 2005-12-01
else {
package_selected = 0;
error = "<nobr>Accept <u>P</u>ackage parameter to generate a Package,<br>" +
"or accept BG<u>A</u> parameter,<br>or <u>U</u>se an existing Package.</nobr>";
PadCount = " ";
}
}
if (!error) {
if ((package_name && !make_Package) && (make_Device && !make_Package)) {
// 2008-11-07 if use a existing package,
// first check padnames in used package
if (!check_exist_pac(strupr(package_name))) error = "Package not exit " + package_name;
else PadCount = getPackagePadCount(package_name); // generate pad list from used package, used_pad_number[]
if (!error) error += check_pin_pad_list(n_pins, strtol(PadCount)); // 2008-11-07
}
if (make_Package) {
if (BGAparameter_accept || packageparameter_accept) ;
else {
error = "Accept BGA or Package parameter.";
}
if (BGAparameter_accept && !n_pins) {
error = "No BSDL file has parsed.";
}
if (package_name) {
m_pac_width = pac_width;
m_grid_val = grid_val;
m_SMD_diameter = SMD_diameter;
m_MaskRestring = MaskRestring;
m_CreamDiameter = CreamDiameter;
}
else {
error = "Define a Package name";
}
}
}
if (!error) {
pac_width = m_pac_width;
grid_val = m_grid_val;
SMD_diameter = m_SMD_diameter;
MaskRestring = m_MaskRestring;
CreamDiameter = m_CreamDiameter;
dlgAccept(); {
// *** make package after set parameter (grid & diameter) 2005-06-28 ***
if (make_Package) {
pac_width = m_pac_width;
grid_val = m_grid_val;
SMD_diameter = m_SMD_diameter;
MaskRestring = m_MaskRestring;
CreamDiameter = m_CreamDiameter;
if (!infile) { library(L) infile = L.name; } // set default path for temporary script 2005-11-03
makePackage(infile);
cmd += "SCRIPT '" + packagefile + "';\nWIN FIT;\n";
}
}
}
else {
display_error(error); // 2008-11-07
}
}
dlgSpacing(8);
dlgPushButton("-Cancel") dlgReject();
dlgStretch(1);
}
dlgSpacing(8);
}
dlgTabPage("BG&A") { // #######################################
dlgSpacing(8);
dlgHBoxLayout {
dlgSpacing(8);
dlgVBoxLayout {
dlgHBoxLayout {
dlgSpacing(8);
dlgLabel("<qt><nobr><font color=red><b>Use only for BSDL file </b></font></nobr></qt>");
}
dlgGroup("Generate Ball Grid Area") {
dlgGridLayout {
dlgCell(2,5) dlgLabel("Body &Width ");
dlgCell(2,6) dlgRealEdit(m_pac_width);
dlgCell(3,5) dlgLabel("PAD &Grid ");
dlgCell(3,6) dlgRealEdit(m_grid_val);
dlgCell(4,5) dlgLabel("PAD &Diameter ");
dlgCell(4,6) dlgRealEdit(m_SMD_diameter);
dlgCell(5,5) dlgLabel("&Stop Mask +/- ");
dlgCell(5,6) dlgRealEdit(m_MaskRestring);
dlgCell(6,5) dlgLabel("&Cream Mask Diam. ");
dlgCell(6,6) dlgRealEdit(m_CreamDiameter);
dlgCell(6,7) dlgLabel(" 0 = OFF");
}
dlgHBoxLayout {
dlgLabel("Drawing grid ");
dlgStringEdit(genpac_grid);
dlgStretch(1);
}
}
dlgStretch(1);
dlgHBoxLayout { // 2009-10-16
dlgStretch(2);
dlgLabel("Generate only BGA pad names, to generate BGA package without a BSDL- or a TEXT-file ");
dlgPushButton("Generate PAD list") genBGA_PadList(); // 2009-10.16
dlgStretch(1);
}
}
dlgLabel("<img src=\"make_bga_package.bmp\">");
dlgStretch(1);
}
dlgStretch(1);
dlgHBoxLayout {
dlgSpacing(8);
dlgCheckBox("Accept para&meter ", BGAparameter_accept) {
genpac_grid = strupr(genpac_grid); // 2008-11-07 use always in upper case
pac_width = m_pac_width; // 2006-06-01
grid_val = m_grid_val;
SMD_diameter = m_SMD_diameter;
MaskRestring = m_MaskRestring;
CreamDiameter = m_CreamDiameter; // 2006-06-09
if (BGAparameter_accept) {
if (!n_pins) {
dlgMessageBox("No BSDL file has parsed.", "OK");
BGAparameter_accept = 0;
}
else {
use_pad_names = useBGA;
packageparameter_accept = 0; // *** only one parameter can accept ***
package_name = strupr(package_name);
gen_package(package_name); // 2005-08-02
make_Package = 1;
MakePacInfo = "Use BGA parameter to generate Package";
}
}
else {
MakePacInfo = " ";
}
}
dlgStretch(1);
}
dlgSpacing(8);
}
dlgTabPage("&Package") { // #######################################
packageparameter_accept = 0;
dlgSpacing(8);
dlgHBoxLayout {
dlgSpacing(8);
dlgVBoxLayout {
dlgGroup("Parameter (generate new package)") {
dlgGridLayout {
dlgCell( 1,0) dlgLabel(" &L ");
dlgCell( 1,1) dlgRealEdit(xA_pac);
dlgCell( 1,2) dlgSpacing(10);
dlgCell( 2,0) dlgLabel(" L1 ");
dlgCell( 2,1) dlgRealEdit(yA_pac);
dlgCell( 4,0) dlgLabel(" &D ");
dlgCell( 4,1) dlgRealEdit(xD_pac);
dlgCell( 5,0) dlgLabel(" D1 ");
dlgCell( 5,1) dlgRealEdit(yD_pac);
dlgCell( 1,4) dlgLabel(" &m ");
dlgCell( 1,5) dlgRealEdit(mark_length);
dlgCell( 2,4) dlgLabel(" &b ");
dlgCell( 2,5) dlgRealEdit(pad_width);
dlgCell( 3,4) dlgLabel(" &e ");
dlgCell( 3,5) dlgRealEdit(basic_pad_grid);
dlgCell( 4,4) dlgLabel(" &w ");
dlgCell( 4,5) dlgRealEdit(pad_stand_out);
dlgCell( 5,4) dlgLabel(" &x ");
dlgCell( 5,5) dlgRealEdit(xpad_length);
dlgCell( 6,4) dlgLabel(" &y"); // 2008-05-20
dlgCell( 6,5) dlgRealEdit(ypad_length);
dlgCell( 7,1) dlgLabel(round_restring, 1); // 2005-12-01
dlgCell( 7,4) dlgLabel(" &r ");
dlgCell( 7,5) dlgRealEdit(roundness_restring, 0, 100);
}
dlgHBoxLayout {
dlgLabel("&Grid ");
dlgStringEdit(genpac_grid);
dlgStretch(1);
}
}
dlgStretch(1);
}
dlgLabel(packinfo, 1);
dlgLabel(packinfomess, 1); // 2005-12-01
dlgVBoxLayout {
dlgGroup("Package PAD Layout") {
dlgGridLayout {
dlgCell(0, 1) dlgLabel("<img src=\"make_package_quad_left.bmp\">");
dlgCell(0, 3) dlgLabel("<img src=\"make_package_quad_middle.bmp\">");
dlgCell(0, 5) dlgLabel("<img src=\"make_package_dual.bmp\">");
dlgCell(1, 1) dlgRadioButton("Quad &1", pad_layout) packinfo = "<img src=\"make_package_meass_pacinfo.bmp\">";
dlgCell(1, 3) dlgRadioButton("Quad &2", pad_layout) packinfo = "<img src=\"make_package_meass_pacinfo.bmp\">";
dlgCell(1, 5) dlgRadioButton("Dual &3", pad_layout) packinfo = "<img src=\"make_package_meass_pacinfo2.bmp\">";
}
dlgStretch(1);
}
dlgHBoxLayout {
dlgGroup("Contact") { // 2005-12-01
dlgGridLayout {
dlgCell( 1,0) dlgRadioButton("SMD", smd_pad) {
packinfomess = "<img src=\"make_package_meass_smdinfo.bmp\">";
round_restring = "Roundness %";
}
dlgCell( 2,0) dlgRadioButton("PAD", smd_pad) {
round_restring = "Restring";
switch(pad_shape) {
case PAD_SHAPE_SQUARE : packinfomess = "<img src=\"make_package_meass_padinfo-sqr.bmp\">";
break;
case PAD_SHAPE_ROUND : packinfomess = "<img src=\"make_package_meass_padinfo-round.bmp\">";
break;
case PAD_SHAPE_OCTAGON : packinfomess = "<img src=\"make_package_meass_padinfo-oct.bmp\">";
break;
}
}
}
}
dlgSpacing(8);
dlgGroup("Shape") {
dlgGridLayout {
dlgCell( 1,0) {
dlgVBoxLayout {
dlgStretch(1);
dlgHBoxLayout {
dlgRadioButton("Square", pad_shape) if (smd_pad) packinfomess = "<img src=\"make_package_meass_padinfo-sqr.bmp\">";
dlgRadioButton("Round", pad_shape) if (smd_pad) packinfomess = "<img src=\"make_package_meass_padinfo-round.bmp\">";
dlgRadioButton("Oct.", pad_shape) if (smd_pad) packinfomess = "<img src=\"make_package_meass_padinfo-oct.bmp\">";
}
}
}
}
}
}
}
dlgStretch(1);
}
dlgStretch(1);
dlgHBoxLayout {
dlgSpacing(8);
dlgCheckBox("A&ccept parameter ", packageparameter_accept) {
genpac_grid = strupr(genpac_grid); // 2008-11-07 use always in upper case
switch (pad_layout) { // check Package PAD placement
case 0 : // quad package with Pin 1 on left side
cnt_side = Pad_Count / 4;
break;
case 1 : // quad package with Pin 1 on middle of top
cnt_side = Pad_Count / 4;
break;
case 2 : // dual in line package
cnt_side = Pad_Count / 2;
break;
}
if (packageparameter_accept) {
string e;
// ** if no package_name defined the script, can not edit a package ".PAC" ** 2005-12-01
if (!package_name) {
sprintf(e, "Error: No Package name defined!\nCheck in TAB Make");
packageparameter_accept = 0;
}
if (pad_layout == 0 || pad_layout == 1) {
int chkpad = Pad_Count % 4; // modulo 4
if (chkpad) {
sprintf(e, "Error: Number of Pads %d can't be devided by 4", Pad_Count);
packageparameter_accept = 0;
}
if (!e) {
int middle = cnt_side % 2;
if (!middle && pad_layout == 1) {
sprintf(e, "Error: Pad layout middle can only be used for an odd number of pads at a side.");
packageparameter_accept = 0;
}
}
}
else if (pad_layout == 2) {
int chkpad = Pad_Count % 2; // modulo 2
if (chkpad) {
sprintf(e, "Error: Number of Pads %d can't be devided by 2", Pad_Count);
packageparameter_accept = 0;
}
}
if (!e) {
if (packageparameter_accept) {
BGAparameter_accept = 0;
use_pad_names = usePACwithPrefix;
package_name = strupr(package_name);
gen_package(package_name); // 2005-08-02
make_Package = 1;
MakePacInfo = "Use package parameter";
}
}
else {
// show error message
MakePacInfo = " ";
dlgMessageBox(e, "OK");
}
}
}
dlgLabel("<qt><nobr><font color=red> not for BGA </font></nobr></qt>");
dlgSpacing(8);
dlgLabel(" Pads Cou&nt ");
dlgIntEdit(Pad_Count, 1, 2000);
dlgSpacing(400);
dlgStretch(1);
}
dlgSpacing(8);
}
dlgTabPage("&Use Package") { // #######################################
dlgSpacing(8);
dlgHBoxLayout {
dlgSpacing(12);
dlgVBoxLayout {
dlgHBoxLayout {
dlgGroup("Package options ") {
dlgRadioButton(" &None", use_pad_names) {
package_selected = 0;
package_name = "";
old_pad_prefix = strupr(pad_prefix);
pad_prefix = "";
}
dlgRadioButton(" Use PAD Na&mes supplied with BSDL file (for BGA parts) ", use_pad_names) {
old_pad_prefix = strupr(pad_prefix);
pad_prefix = "";
}
dlgRadioButton(" Use PAD Prefi&x if existing package is used ", use_pad_names) {
old_pad_prefix = strupr(pad_prefix);
pad_prefix = old_pad_prefix;
}
}
dlgSpacing(8);
dlgStretch(1);
}
dlgSpacing(8);
dlgHBoxLayout {
dlgLabel(" Use &existing package ");
dlgComboBox(packages, package_selected) {
PadCount = "check pad names, please wait.. "; // 2008-11-07
dlgRedisplay();
package_name = packages[package_selected];
if (!package_selected) {
pad_prefix = getPackagePadPrefix(packages[package_selected]);
package_name = "";
}
else package_name = packages[package_selected]; // 2008-11-07
status("generate pad list from package");
PadCount = getPackagePadCount(package_name); // generate pad list from used package, used_pad_number[]
dlgRedisplay();
status("");
if (package_selected) make_Package = 0; // if use a package do not generate package
}
dlgLabel(PadCount, 1);
dlgStretch(1);
}
dlgSpacing(8);
dlgHBoxLayout {
dlgLabel(" Pad prefi&x ");
dlgStringEdit(pad_prefix);
dlgSpacing(560);
dlgStretch(1);
}
dlgSpacing(8);
}
}
dlgStretch(1);
}
dlgTabPage("&Text Options") { // #######################################
if (is_bsdl) {
dlgLabel("BSDL file in use! Do not change this text!");
}
else {
dlgHBoxLayout {
dlgStretch(1);
dlgPushButton("Swap PIN <-> PAD") {
if (is_bsdl) {
dlgMessageBox("!Do not swap Pin - Pad if a BSDL file is used!", "Ok");
}
else {
for (int i = 0; i < n_pins; i++) {
string tt;
tt = pins[i];
pins[i] = pads[i];
pads[i] = tt;
tt = pin_names[i];
pin_names[i] = pad_names[i];
pad_names[i] = tt;
}
gen_viewlist(n_pins);
}
}
dlgPushButton("Swap PAD <&-> DIR") {
if (is_bsdl) {
dlgMessageBox("!Do not swap PAD - DIR if a BSDL file is used!", "Ok");
}
else {
for (int i = 0; i < n_pins; i++) {
string tt;
tt = pad_names[i];
pad_names[i] = pin_direc[i];
pin_direc[i] = tt;
pads[i] = pad_names[i];
}
gen_viewlist(n_pins);
}
}
dlgPushButton("Del&. Direct.") {
if (is_bsdl) {
dlgMessageBox("!Do not delete DIR if a BSDL file is used!", "Ok");
}
else {
for (int i = 0; i < n_pins; i++) {
pin_direc[i] = "";
}
gen_viewlist(n_pins);
}
}
}
dlgHBoxLayout {
dlgSpacing(8);
dlgGroup("Use with text only, not with a BSDL file") {
dlgVBoxLayout {
dlgHBoxLayout {
dlgSpacing(160);
dlgLabel("** use also for Parse -->>");
dlgStretch(1);
}
dlgHBoxLayout {
dlgPushButton("Spl&it") {
change_char_text(w_separator[select_separ], '\n', 0);
}
dlgLabel(" with word &separator ");
dlgComboBox(separator, select_separ) {
Word_separator = w_separator[select_separ];
sprintf(String_separator, "%c", Word_separator);
}
dlgSpacing(16);
dlgLabel("Split with ");
dlgPushButton("&Character ") {
if (strlen(c_separator) == 1)
change_char_text(c_separator[0], '\n', 0);
else if (c_separator)
dlgMessageBox("!Split with character.\nMore than 1 character in this field.", "Ok");
else
dlgMessageBox("!Split with character\nNo character defined.", "Ok");
}
dlgLabel(" separator ");
dlgStringEdit(c_separator);
}
dlgSpacing(4);
dlgHBoxLayout {
dlgPushButton("&Merge") {
if (separator_counter > 1) {
int cntnl = strsplit(st, text, '\n');
text = "";
cc = 0;
int cnt = 0;
for (int n = 0; n < cntnl; n++) {
text += st[n];
if (cnt < separator_counter-1) {
text += String_separator;
cnt++;
}
else {
text += "\n";
cnt = 0;
cc++;
}
}
if(strlen(text) > 0) {
text[strlen(text)-1] = 0;
sprintf(tinfo, "<nobr>shrink %d to %d lines</nobr>", cntnl, cc);
}
}
else {
dlgMessageBox("Counter must be >= 2", "ok");
}
}
dlgSpacing(4);
dlgIntEdit(separator_counter);
dlgLabel(" lines with word separator");
dlgSpacing(190);
dlgStretch(1);
}
dlgSpacing(4);
dlgHBoxLayout {
dlgPushButton("&Replace" ) replaceWord(search, replace);
dlgLabel(" character strin&g ");
dlgStringEdit(search);
dlgLabel(" &with ");
dlgStringEdit(replace);
}
dlgSpacing(4);
dlgHBoxLayout {
dlgPushButton("D&elete") {
int cntst = strsplit(st, text, '\n');
text = "";
for (int n = 0; n < cntst; n++) {
if (exact_include) {
if (strstr(st[n], del_line) < 0) text += st[n] + "\n";
}
else if (st[n] != del_line) text += st[n] + "\n";
}
}
dlgLabel(" lines with te&xt string ");
dlgStringEdit(del_line);
dlgSpacing(8);
dlgRadioButton("Exact", exact_include);
dlgRadioButton("Include", exact_include);
dlgStretch(1);
}
dlgSpacing(4);
dlgHBoxLayout {
dlgPushButton("&Delete") delete_x_line(start_line, x_line);
dlgLabel(" e&very ");
dlgIntEdit(x_line);
dlgLabel("th. line. Start at &line ");
dlgIntEdit(start_line);
dlgStretch(1);
}
dlgSpacing(4);
dlgHBoxLayout {
dlgPushButton("Delete empt&y lines") delete_empty_lines();
dlgStretch(1);
}
dlgSpacing(4);
dlgHBoxLayout {
dlgPushButton("Delete column") delete_column(delColumn); // 2008-04-02
dlgLabel(" column &# ");
dlgIntEdit(delColumn, 1, 100);
dlgLabel(" (count from 1) ");
dlgStretch(1);
}
}
}
dlgStretch(1);
dlgVBoxLayout {
dlgSpacing(8);
dlgHBoxLayout {
dlgStretch(1);
dlgPushButton("Clear leading zeros in BGA-Pad") clear_leading_z(n_pins);
dlgStretch(1);
}
dlgSpacing(8);
dlgHBoxLayout {
dlgStretch(1);
dlgPushButton("Change direction") change_dir(n_pins); // 2008-04-02
dlgStretch(1);
}
dlgSpacing(8);
dlgHBoxLayout {
dlgStretch(1);
dlgPushButton("Set pin direction") {
set_pin_direction(n_pins); // 2008-07-03
}
dlgStretch(1);
}
dlgSpacing(8);
dlgHBoxLayout {
dlgStretch(1);
dlgPushButton("Delete double pad number") {
n_pins = del_double_pad(n_pins); // 2008-04-02
}
dlgStretch(1);
}
dlgSpacing(8);
dlgHBoxLayout {
dlgStretch(1);
dlgPushButton("Rename PAD") {
rename_pad(n_pins, search, replace); // 2008-11-07
}
dlgStretch(1);
}
dlgSpacing(8);
dlgHBoxLayout {
dlgStretch(1);
dlgPushButton("Numbering pins for pad number") {
number_pins(n_pins); // 2008-07-03
}
dlgStretch(1);
}
dlgStretch(1);
dlgLabel("<hr>");
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);
}