Basic support in tgt-pcb for reading footprint files.
When a black-box item requests a specific footprint, we need to read a file (<footprint>.fp) that contains the actual details about that footprint. Support parse of that file and use the loaded Element to generate the footprint for the item.
This commit is contained in:
parent
a95d64b7de
commit
5451a4830f
|
|
@ -29,6 +29,10 @@ Makefile
|
||||||
/_pli_types.h
|
/_pli_types.h
|
||||||
config.h
|
config.h
|
||||||
/tgt-pcb/pcb_config.h
|
/tgt-pcb/pcb_config.h
|
||||||
|
/tgt-pcb/fp.cc
|
||||||
|
/tgt-pcb/fp.h
|
||||||
|
/tgt-pcb/fp.output
|
||||||
|
/tgt-pcb/fp_lex.cc
|
||||||
/tgt-vvp/vvp_config.h
|
/tgt-vvp/vvp_config.h
|
||||||
/tgt-vhdl/vhdl_config.h
|
/tgt-vhdl/vhdl_config.h
|
||||||
/vpi/vpi_config.h
|
/vpi/vpi_config.h
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ CXX = @CXX@
|
||||||
INSTALL = @INSTALL@
|
INSTALL = @INSTALL@
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
LEX = @LEX@
|
||||||
|
YACC = @YACC@
|
||||||
|
|
||||||
ifeq (@srcdir@,.)
|
ifeq (@srcdir@,.)
|
||||||
INCLUDE_PATH = -I. -I..
|
INCLUDE_PATH = -I. -I..
|
||||||
|
|
@ -45,7 +47,7 @@ CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||||
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
|
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
|
||||||
LDFLAGS = @LDFLAGS@
|
LDFLAGS = @LDFLAGS@
|
||||||
|
|
||||||
O = pcb.o scope.o show_netlist.o show_pcb.o
|
O = pcb.o scope.o show_netlist.o show_pcb.o footprint.o fp.o fp_lex.o
|
||||||
|
|
||||||
all: dep pcb.tgt
|
all: dep pcb.tgt
|
||||||
|
|
||||||
|
|
@ -74,6 +76,13 @@ dep:
|
||||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||||
mv $*.d dep
|
mv $*.d dep
|
||||||
|
|
||||||
|
fp_lex.cc: $(srcdir)/fp.lex
|
||||||
|
$(LEX) -s -ofp_lex.cc $(srcdir)/fp.lex
|
||||||
|
|
||||||
|
fp.cc fp.h: $(srcdir)/fp.y
|
||||||
|
$(YACC) --verbose -t -d -o fp.cc $(srcdir)/fp.y
|
||||||
|
mv fp.cc.h fp.h 2>/dev/null || mv fp.hh fp.h
|
||||||
|
|
||||||
ifeq (@WIN32@,yes)
|
ifeq (@WIN32@,yes)
|
||||||
TGTLDFLAGS=-L.. -livl
|
TGTLDFLAGS=-L.. -livl
|
||||||
TGTDEPLIBS=../libivl.a
|
TGTDEPLIBS=../libivl.a
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
# include "version_base.h"
|
||||||
|
# include "version_tag.h"
|
||||||
|
# include "pcb_config.h"
|
||||||
|
# include "pcb_priv.h"
|
||||||
|
# include "fp_api.h"
|
||||||
|
# include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
map<string,fp_element_t> footprints;
|
||||||
|
|
||||||
|
static int check_footprint(element_data_t*elem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scan the element list and collect footprints needed.
|
||||||
|
*/
|
||||||
|
int load_footprints(void)
|
||||||
|
{
|
||||||
|
for (map<string,element_data_t*>::const_iterator cur = element_list.begin()
|
||||||
|
; cur != element_list.end() ; ++ cur) {
|
||||||
|
check_footprint(cur->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The fpparse funciton calls back the callback_fp_element function
|
||||||
|
* for each Element that it parses. The check_footprint function
|
||||||
|
* stores in the cur_footprint variable the name of the footprint that
|
||||||
|
* we are trying to find in the file. The callback uses that name to
|
||||||
|
* store the Element into the footprints map.
|
||||||
|
*/
|
||||||
|
static string cur_footprint = "";
|
||||||
|
void callback_fp_element(const struct fp_element_t&cur_elem)
|
||||||
|
{
|
||||||
|
assert(cur_footprint != "");
|
||||||
|
footprints[cur_footprint] = cur_elem;
|
||||||
|
cur_footprint = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int check_footprint(element_data_t*elem)
|
||||||
|
{
|
||||||
|
if (elem->footprint == "") {
|
||||||
|
cerr << "No footprint defined for \"" << elem->description << "\"." << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
map<string,fp_element_t>::iterator match = footprints.find(elem->footprint);
|
||||||
|
if (match != footprints.end())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
string fpname = elem->footprint + ".fp";
|
||||||
|
|
||||||
|
cur_footprint = elem->footprint;
|
||||||
|
int rc = parse_fp_file(fpname);
|
||||||
|
if (rc != 0) {
|
||||||
|
cerr << "parse_fp_file(" << fpname << ") returns rc=" << rc << endl;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
match = footprints.find(elem->footprint);
|
||||||
|
if (match == footprints.end()) {
|
||||||
|
cerr << "Unable to locate footprint " << elem->footprint << "." << endl;
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
%option prefix="fp"
|
||||||
|
%option never-interactive
|
||||||
|
%option noinput
|
||||||
|
%option nounput
|
||||||
|
%option noyywrap
|
||||||
|
%option reentrant
|
||||||
|
|
||||||
|
%{
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* 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.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
# include "fp_api.h"
|
||||||
|
# include "fp.h"
|
||||||
|
|
||||||
|
# define YY_DECL int yylex(YYSTYPE*yylvalp, YYLTYPE*yyllocp, yyscan_t yyscanner)
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
SPACE [ \t\f\r]
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
/* Skip comment lines */
|
||||||
|
"#".* { ; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Skip white space */
|
||||||
|
{SPACE} { ; }
|
||||||
|
"\n" { yyllocp->first_line += 1; }
|
||||||
|
|
||||||
|
"Element" { return K_ELEMENT; }
|
||||||
|
"Pad" { return K_PAD; }
|
||||||
|
|
||||||
|
"0x"[0-9a-fA-F]+ {
|
||||||
|
yylvalp->integer = strtoul(yytext+2,0,10);
|
||||||
|
return INTEGER;
|
||||||
|
}
|
||||||
|
|
||||||
|
"0"[0-7]* {
|
||||||
|
yylvalp->integer = strtoul(yytext,0,8);
|
||||||
|
return INTEGER;
|
||||||
|
}
|
||||||
|
|
||||||
|
[1-9][0-9]* {
|
||||||
|
yylvalp->integer = strtoul(yytext,0,10);
|
||||||
|
return INTEGER;
|
||||||
|
}
|
||||||
|
|
||||||
|
"\""[^\"]*"\"" {
|
||||||
|
size_t len = strlen(yytext)-2;
|
||||||
|
char*tmp = new char[len+1];
|
||||||
|
memcpy(tmp, yytext+1, len);
|
||||||
|
tmp[len] = 0;
|
||||||
|
yylvalp->text = tmp;
|
||||||
|
return STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Isolated characters are tokens */
|
||||||
|
. { return yytext[0]; }
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
yyscan_t prepare_fp_lexor(FILE*fd)
|
||||||
|
{
|
||||||
|
yyscan_t scanner;
|
||||||
|
yylex_init(&scanner);
|
||||||
|
yyrestart(fd, scanner);
|
||||||
|
return scanner;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_fp_lexor(yyscan_t scanner)
|
||||||
|
{
|
||||||
|
yylex_destroy(scanner);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,200 @@
|
||||||
|
|
||||||
|
%name-prefix="fp"
|
||||||
|
%pure-parser
|
||||||
|
%lex-param {yyscan_t yyscanner}
|
||||||
|
%parse-param {yyscan_t yyscanner}
|
||||||
|
%parse-param {const char*file_path}
|
||||||
|
|
||||||
|
%{
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
# include "fp_api.h"
|
||||||
|
# include "pcb_priv.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
/* Recent version of bison expect that the user supply a
|
||||||
|
YYLLOC_DEFAULT macro that makes up a yylloc value from existing
|
||||||
|
values. I need to supply an explicit version to account for the
|
||||||
|
text field, that otherwise won't be copied. */
|
||||||
|
# define YYLLOC_DEFAULT(Current, Rhs, N) do { \
|
||||||
|
(Current).first_line = (Rhs)[1].first_line; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static void yyerror(YYLTYPE*yylloc, yyscan_t scanner, const char*file_path, const char*msg)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s\n", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern yyscan_t prepare_fp_lexor(FILE*fd);
|
||||||
|
extern void destroy_fp_lexor(yyscan_t scanner);
|
||||||
|
extern int fplex(union YYSTYPE*yylvalp, YYLTYPE*yylloc, yyscan_t scanner);
|
||||||
|
|
||||||
|
static fp_pad_t cur_pad;
|
||||||
|
static fp_element_t cur_element;
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%union {
|
||||||
|
long integer;
|
||||||
|
char*text;
|
||||||
|
};
|
||||||
|
|
||||||
|
%token <text> STRING
|
||||||
|
%token <integer> INTEGER
|
||||||
|
%token K_ELEMENT
|
||||||
|
%token K_PAD
|
||||||
|
|
||||||
|
%type <integer> integer
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
file_items : file_items file_item | file_item ;
|
||||||
|
|
||||||
|
file_item : element ;
|
||||||
|
|
||||||
|
element
|
||||||
|
: K_ELEMENT element_header '(' element_items ')'
|
||||||
|
{ callback_fp_element(cur_element); }
|
||||||
|
;
|
||||||
|
|
||||||
|
element_header
|
||||||
|
: '[' INTEGER STRING STRING STRING integer integer integer integer integer integer STRING ']'
|
||||||
|
{ cur_element.nflags = $2;
|
||||||
|
cur_element.description = $3; delete[]$3;
|
||||||
|
cur_element.name = $4; delete[]$4;
|
||||||
|
cur_element.value = $5; delete[]$5;
|
||||||
|
cur_element.mx = $6;
|
||||||
|
cur_element.my = $7;
|
||||||
|
cur_element.tx = $8;
|
||||||
|
cur_element.ty = $9;
|
||||||
|
cur_element.tdir = $10;
|
||||||
|
cur_element.tscale = $11;
|
||||||
|
cur_element.tsflags = $12; delete[]$12;
|
||||||
|
cur_element.pads.clear();
|
||||||
|
}
|
||||||
|
| '[' error ']'
|
||||||
|
{ errormsg(@2, "Error in element header\n");
|
||||||
|
yyerrok;
|
||||||
|
cur_element.nflags = 0;
|
||||||
|
cur_element.description = "";
|
||||||
|
cur_element.name = "";
|
||||||
|
cur_element.value = "";
|
||||||
|
cur_element.mx = 0;
|
||||||
|
cur_element.my = 0;
|
||||||
|
cur_element.tx = 0;
|
||||||
|
cur_element.ty = 0;
|
||||||
|
cur_element.tdir = 0;
|
||||||
|
cur_element.tscale = 0;
|
||||||
|
cur_element.tsflags = "";
|
||||||
|
cur_element.pads.clear();
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
element_items
|
||||||
|
: element_items element_item
|
||||||
|
| element_item
|
||||||
|
;
|
||||||
|
|
||||||
|
element_item
|
||||||
|
: pad { cur_element.pads[cur_pad.name] = cur_pad; }
|
||||||
|
;
|
||||||
|
|
||||||
|
integer
|
||||||
|
: INTEGER { $$ = $1; }
|
||||||
|
| '-' INTEGER { $$ = -$2; }
|
||||||
|
;
|
||||||
|
|
||||||
|
pad
|
||||||
|
: K_PAD '[' integer integer integer integer integer integer integer STRING STRING STRING ']'
|
||||||
|
{ cur_pad.rx1 = $3;
|
||||||
|
cur_pad.ry1 = $4;
|
||||||
|
cur_pad.rx2 = $5;
|
||||||
|
cur_pad.ry2 = $6;
|
||||||
|
cur_pad.thickness = $7;
|
||||||
|
cur_pad.clearance = $8;
|
||||||
|
cur_pad.mask = $9;
|
||||||
|
cur_pad.name = $10; delete[]$10;
|
||||||
|
cur_pad.number = $11; delete[]$11;
|
||||||
|
cur_pad.sflags = $12; delete[]$12;
|
||||||
|
}
|
||||||
|
|
||||||
|
| K_PAD '[' error ']'
|
||||||
|
{ errormsg(@3, "Error in pad header\n");
|
||||||
|
yyerrok;
|
||||||
|
cur_pad.rx1 = 0;
|
||||||
|
cur_pad.ry1 = 0;
|
||||||
|
cur_pad.rx2 = 0;
|
||||||
|
cur_pad.ry2 = 0;
|
||||||
|
cur_pad.thickness = 0;
|
||||||
|
cur_pad.clearance = 0;
|
||||||
|
cur_pad.mask = 0;
|
||||||
|
cur_pad.name = "";
|
||||||
|
cur_pad.number = "";
|
||||||
|
cur_pad.sflags = "";
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
static string parse_file_path;
|
||||||
|
int parse_fp_errors = 0;
|
||||||
|
int parse_fp_sorrys = 0;
|
||||||
|
|
||||||
|
void errormsg(const YYLTYPE&loc, const char*fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
|
||||||
|
fprintf(stderr, "%s:%d: error: ", parse_file_path.c_str(), loc.first_line);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
parse_fp_errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sorrymsg(const YYLTYPE&loc, const char*fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
|
||||||
|
fprintf(stderr, "%s:%d: sorry: ", parse_file_path.c_str(), loc.first_line);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
parse_fp_sorrys += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_fp_file(const string&file_path)
|
||||||
|
{
|
||||||
|
FILE*fd = fopen(file_path.c_str(), "r");
|
||||||
|
if (fd == 0) {
|
||||||
|
perror(file_path.c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_file_path = file_path;
|
||||||
|
parse_fp_errors = 0;
|
||||||
|
parse_fp_sorrys = 0;
|
||||||
|
yyscan_t scanner = prepare_fp_lexor(fd);
|
||||||
|
int rc = yyparse(scanner, file_path.c_str());
|
||||||
|
fclose(fd);
|
||||||
|
destroy_fp_lexor(scanner);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
#ifndef __fp_api_H
|
||||||
|
#define __fp_api_H
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
# include <string>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the interface function that the user invokes to parse a
|
||||||
|
* footprint file. The argument is the path to the element.
|
||||||
|
*/
|
||||||
|
extern int parse_fp_file(const std::string&file_path);
|
||||||
|
|
||||||
|
typedef void*yyscan_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The yyltype supports the passing of detailed source file location
|
||||||
|
* information between the lexical analyzer and the parser. Defining
|
||||||
|
* YYLTYPE compels the lexor to use this type and not something other.
|
||||||
|
*/
|
||||||
|
struct yyltype {
|
||||||
|
unsigned first_line;
|
||||||
|
yyltype() { first_line = 1; }
|
||||||
|
};
|
||||||
|
# define YYLTYPE struct yyltype
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use this function during parse to generate error messages. The "loc"
|
||||||
|
* is the location of the token that triggered the error, and the fmt
|
||||||
|
* is printf-style format.
|
||||||
|
*/
|
||||||
|
extern void errormsg(const YYLTYPE&loc, const char*fmt, ...) __attribute__((format (printf, 2, 3)));
|
||||||
|
|
||||||
|
extern void sorrymsg(const YYLTYPE&loc, const char*fmt, ...) __attribute__((format (printf, 2, 3)));
|
||||||
|
|
||||||
|
extern void callback_fp_element(const struct fp_element_t&);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set this to a non-zero value to enable parser debug output.
|
||||||
|
*/
|
||||||
|
//extern int yydebug;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The parser counts the errors that is handed in the parse_errors
|
||||||
|
* variable. For a clean compile, this value should not change. (The
|
||||||
|
* caller sets its initial value.) The sorrys are the count of
|
||||||
|
* unsupported constructs that are encountered.
|
||||||
|
*/
|
||||||
|
//extern int parse_errors;
|
||||||
|
extern int parse_fp_sorrys;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -64,6 +64,8 @@ int target_design(ivl_design_t des)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
load_footprints();
|
||||||
|
|
||||||
assert(pcb_path);
|
assert(pcb_path);
|
||||||
show_pcb(pcb_path);
|
show_pcb(pcb_path);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,10 +48,40 @@ extern std::list<struct nexus_data*> nexus_list;
|
||||||
struct element_data_t {
|
struct element_data_t {
|
||||||
std::string description;
|
std::string description;
|
||||||
std::string value;
|
std::string value;
|
||||||
|
std::string footprint;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::map <std::string, element_data_t*> element_list;
|
extern std::map <std::string, element_data_t*> element_list;
|
||||||
|
|
||||||
|
extern int load_footprints(void);
|
||||||
|
|
||||||
|
struct fp_pad_t {
|
||||||
|
long rx1, ry1;
|
||||||
|
long rx2, ry2;
|
||||||
|
int thickness;
|
||||||
|
int clearance;
|
||||||
|
int mask;
|
||||||
|
std::string name;
|
||||||
|
std::string number;
|
||||||
|
std::string sflags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fp_element_t {
|
||||||
|
long nflags;
|
||||||
|
std::string description;
|
||||||
|
std::string name;
|
||||||
|
std::string value;
|
||||||
|
long mx, my;
|
||||||
|
long tx, ty;
|
||||||
|
int tdir;
|
||||||
|
int tscale;
|
||||||
|
std::string tsflags;
|
||||||
|
|
||||||
|
std::map<std::string,fp_pad_t> pads;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::map<std::string,fp_element_t> footprints;
|
||||||
|
|
||||||
extern void show_netlist(const char*net_path);
|
extern void show_netlist(const char*net_path);
|
||||||
|
|
||||||
extern void show_pcb(const char*pcb_path);
|
extern void show_pcb(const char*pcb_path);
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,16 @@ static void black_box(ivl_scope_t scope, const map<string,attr_value>&attrs)
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (name == "footprint") {
|
||||||
|
ivl_expr_t exp = ivl_parameter_expr(par);
|
||||||
|
switch (ivl_expr_type(exp)) {
|
||||||
|
case IVL_EX_STRING:
|
||||||
|
elem_data->footprint = ivl_expr_string(exp);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ static void show_pcb_header(FILE*fpcb)
|
||||||
fprintf(fpcb, "Grid[100.0 0 0 1]\n");
|
fprintf(fpcb, "Grid[100.0 0 0 1]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void show_pcb_element(FILE*fpcb, const string&refdes, element_data_t*elem);
|
||||||
|
|
||||||
void show_pcb(const char*pcb_path)
|
void show_pcb(const char*pcb_path)
|
||||||
{
|
{
|
||||||
|
|
@ -44,9 +45,17 @@ void show_pcb(const char*pcb_path)
|
||||||
for (map<string,element_data_t*>::const_iterator cur = element_list.begin()
|
for (map<string,element_data_t*>::const_iterator cur = element_list.begin()
|
||||||
; cur != element_list.end() ; ++ cur) {
|
; cur != element_list.end() ; ++ cur) {
|
||||||
|
|
||||||
const string&refdes = cur->first;
|
show_pcb_element(fpcb, cur->first, cur->second);
|
||||||
const string&descr = cur->second->description;
|
}
|
||||||
const string&value = cur->second->value;
|
|
||||||
|
fclose(fpcb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_pcb_element(FILE*fpcb, const string&refdes, element_data_t*elem)
|
||||||
|
{
|
||||||
|
string descr = elem->description;
|
||||||
|
const string&value = elem->value;
|
||||||
|
if (elem->footprint == "") {
|
||||||
fprintf(fpcb, "Element[\"\" \"%s\" \"%s\" \"%s\"",
|
fprintf(fpcb, "Element[\"\" \"%s\" \"%s\" \"%s\"",
|
||||||
descr.c_str(), refdes.c_str(), value.c_str());
|
descr.c_str(), refdes.c_str(), value.c_str());
|
||||||
|
|
||||||
|
|
@ -60,7 +69,35 @@ void show_pcb(const char*pcb_path)
|
||||||
// from a library.
|
// from a library.
|
||||||
fprintf(fpcb, "(\n");
|
fprintf(fpcb, "(\n");
|
||||||
fprintf(fpcb, ")\n");
|
fprintf(fpcb, ")\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fpcb);
|
fp_element_t&foot = footprints[elem->footprint];
|
||||||
|
if (descr == "")
|
||||||
|
descr = foot.description;
|
||||||
|
fprintf(fpcb, "Element[0x%lx \"%s\" \"%s\" \"%s\"",
|
||||||
|
foot.nflags, descr.c_str(), refdes.c_str(), value.c_str());
|
||||||
|
|
||||||
|
fprintf(fpcb, " %ld %ld", foot.mx, foot.my);
|
||||||
|
fprintf(fpcb, " %ld %ld %d %d \"%s\"", foot.tx, foot.ty, foot.tdir,
|
||||||
|
foot.tscale, foot.tsflags.c_str());
|
||||||
|
|
||||||
|
fprintf(fpcb, "]\n(\n");
|
||||||
|
|
||||||
|
for (map<string,fp_pad_t>::const_iterator cur = foot.pads.begin()
|
||||||
|
; cur != foot.pads.end() ; ++ cur) {
|
||||||
|
fprintf(fpcb, "Pad[%ld %ld %ld %ld %d %d %d \"%s\" \"%s\" \"%s\"]\n",
|
||||||
|
cur->second.rx1,
|
||||||
|
cur->second.ry1,
|
||||||
|
cur->second.rx2,
|
||||||
|
cur->second.ry2,
|
||||||
|
cur->second.thickness,
|
||||||
|
cur->second.clearance,
|
||||||
|
cur->second.mask,
|
||||||
|
cur->second.name.c_str(),
|
||||||
|
cur->second.number.c_str(),
|
||||||
|
cur->second.sflags.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fpcb, ")\n");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue