#usage "Make Symbol, Device, Package or use Package in LBR\n" "

" "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.
" "

" "Author: ed@anuff.com / librarian@cadsoft.de" #require 4.1600 /* * Copyright (c) 2004 Ed Anuff . 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 = "Dieses ULP unterstützt die Generierung von Symbolen, Devices und Packages.
" + "Eine BSDL-Datei (Boundary Scan Description Language .bsdl) wird automatisch geparsed.
" + "Pin-Direction: Der Bezeichner 'linkage' wird für No-Connects (NC), Power (VCC), oder Ground (GND) benutzt, wobei anhand der BSDL-Daten
"+ "nicht unterschieden werden kann ob es sich um einen NC oder PWR Pin handelt.
"+ "In einigen Fällen kann es vorkommen das dadurch Signalpins die Direction PWR erhalten, die man manuell im Symbol-Editor ändern muß.

"+ "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:
" + "

" + "Durch Anwenden der einzelnen Möglichkeiten kann ein beliebiger Text zu einer brauchbaren Tabelle umgestaltet werden.
" + "Es ist auch möglich einen Text aus der Zwischenablage einzufügen." + "

" + "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.

" + "Author: librarian@cadsoft.de"; ""; string HelpEN = "This ULP supports the generation of Symbols, Devices, and Packages.
" + "A BSDL (Boundary Scan Description Language) file will be parsed automatically
" + "PIN-Direction: 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).

"+ "The number of separators in the text file determins and presets the word separator.

" + "There are the following possibilities to edit text files (spreadsheets):
" + "

" + "These tools allow to make a usable spreadsheet from any text." + "It is also possible to insert text from the operating sytem's clipboard.
" + "If you are working with text files you have to choose an already existing package from the currently loaded library or use Package.
" + "It is also possible to generate a new package from a BSDL file (*.bsdl).
" + "First the ULP will check if there are sufficient pads for the pins of the symbol.
" + "

" + "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." + "

" + "Author: librarian@cadsoft.de"; ""; string Help; if (language() == "de") Help = HelpDE; else Help = HelpEN; string editMode = " edit this description"; 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 = ""; // 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, "Too much pins to generate symbol in X
Coordinate (%.4f) %s out of range %.4f %s

", x, grid_unit, maxminxy, grid_unit); } if (y > maxminxy || y < -maxminxy) { sprintf(s, "Too much pins to generate symbol in Y
Coordinate (%.4f) %s out of range %.4f %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"; else if (edit_type == bga_pac) s += "Check pad names in BSDL file
" + 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, "%d words replaced", 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("found next MAP list " + next_pin_map + " (Package), last Map list " + package_name + " (Package)

Use MAP?", 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, "Too many pins for a small symbol. Tip: Generate symbol with stripes of max pins in line."); // 2006-12-05 pin_layout = k_stripe; } else if (n_pins > maxPinCnt) { sprintf(pinCntInfo, "Too many pins for a small symbol. Generate symbol with four sides."); pin_layout = k_quad; // 2008-11-07 } sprintf( bsdl_package_name, "Used package in BSDL file: %s", 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 = "Parsing BSDL file, please wait!"; parsed_pins = "Please wait!"; 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, "[text length %d character]", 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 '%s%s

\\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, "%d characters changed.", 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 = "It is absurd to delete all lines! Check the value of x. line"; 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, "%d %d. lines deleted", cdel, x); else sprintf(tinfo, "%d second lines deleted", cdel); return; } void delete_empty_lines(void) { if(!text) { tinfo = "List is empty!"; 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, "%d empty lines deleted", cc); return; } void delete_column(int del_column) { // 2008-04-02 if (!text) { tinfo = "List is empty!"; return; } if (!del_column) { tinfo = "First set the number of column to delete!"; 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 = "Finsh clear leading zeros"; 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, "Finsh delete double (%d) pad name, new count %d", 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!
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 = "Tip: Use split-device-symbol.ulp to generate a Device with multiple small symbols! Read HELP."; // 2006-12-05 dlgCell(0, 9) dlgLabel(""); 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 = "Accept Package parameter to generate a Package,
" + "or accept BGA parameter,
or Use an existing Package.
"; 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("Use only for BSDL file "); } 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(""); 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(""); dlgCell(0, 3) dlgLabel(""); dlgCell(0, 5) dlgLabel(""); dlgCell(1, 1) dlgRadioButton("Quad &1", pad_layout) packinfo = ""; dlgCell(1, 3) dlgRadioButton("Quad &2", pad_layout) packinfo = ""; dlgCell(1, 5) dlgRadioButton("Dual &3", pad_layout) packinfo = ""; } dlgStretch(1); } dlgHBoxLayout { dlgGroup("Contact") { // 2005-12-01 dlgGridLayout { dlgCell( 1,0) dlgRadioButton("SMD", smd_pad) { packinfomess = ""; round_restring = "Roundness %"; } dlgCell( 2,0) dlgRadioButton("PAD", smd_pad) { round_restring = "Restring"; switch(pad_shape) { case PAD_SHAPE_SQUARE : packinfomess = ""; break; case PAD_SHAPE_ROUND : packinfomess = ""; break; case PAD_SHAPE_OCTAGON : packinfomess = ""; break; } } } } dlgSpacing(8); dlgGroup("Shape") { dlgGridLayout { dlgCell( 1,0) { dlgVBoxLayout { dlgStretch(1); dlgHBoxLayout { dlgRadioButton("Square", pad_shape) if (smd_pad) packinfomess = ""; dlgRadioButton("Round", pad_shape) if (smd_pad) packinfomess = ""; dlgRadioButton("Oct.", pad_shape) if (smd_pad) packinfomess = ""; } } } } } } } 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(" not for BGA "); 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, "shrink %d to %d lines", 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("


"); 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); }