mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-22 02:08:26 +02:00
More work on holes: added documentation and Postscript output.
- overlap.c (inside, test_overlap): check for instance type - overlap.c (inside, test_overlap): support hole instances - README: put a pointer to the GUI description at the beginning - README, gui.html: documented role and creation of holes - inst.h: holes can now link to pads and vice versa - hole.c, obj.c (instantiate): connect holes with pads and apply consistency checks - postscript.c: added output for holes - icons/hole.fig: make hatched surroundings of hole look more round git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5940 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
parent
1dda2ac2ae
commit
6db067a90f
2
Makefile
2
Makefile
@ -16,7 +16,7 @@ UPLOAD = werner@sita.openmoko.org:public_html/fped/
|
|||||||
|
|
||||||
OBJS = fped.o expr.o coord.o obj.o delete.o inst.o util.o error.o \
|
OBJS = fped.o expr.o coord.o obj.o delete.o inst.o util.o error.o \
|
||||||
unparse.o file.o dump.o kicad.o postscript.o meas.o \
|
unparse.o file.o dump.o kicad.o postscript.o meas.o \
|
||||||
layer.o overlap.o \
|
layer.o overlap.o hole.o \
|
||||||
cpp.o lex.yy.o y.tab.o \
|
cpp.o lex.yy.o y.tab.o \
|
||||||
gui.o gui_util.o gui_style.o gui_inst.o gui_status.o gui_canvas.o \
|
gui.o gui_util.o gui_style.o gui_inst.o gui_status.o gui_canvas.o \
|
||||||
gui_tool.o gui_over.o gui_meas.o gui_frame.o gui_frame_drag.o
|
gui_tool.o gui_over.o gui_meas.o gui_frame.o gui_frame_drag.o
|
||||||
|
22
README
22
README
@ -9,6 +9,11 @@ The language is constrained such that anything that can be expressed in
|
|||||||
the textual definition also has a straightforward equivalent operation
|
the textual definition also has a straightforward equivalent operation
|
||||||
that can be performed through the GUI.
|
that can be performed through the GUI.
|
||||||
|
|
||||||
|
This README describes only the footprint definition language. A
|
||||||
|
description of the GUI can be found here:
|
||||||
|
|
||||||
|
http://people.openmoko.org/werner/fped/gui.html
|
||||||
|
|
||||||
This work is distributed under the terms of the GNU GENERAL PUBLIC
|
This work is distributed under the terms of the GNU GENERAL PUBLIC
|
||||||
LICENSE, Version 2:
|
LICENSE, Version 2:
|
||||||
|
|
||||||
@ -251,6 +256,23 @@ If enclosed in a square, rounded pads form a circle.
|
|||||||
rpad "<name>" <point-a> <point-b> [<type>]
|
rpad "<name>" <point-a> <point-b> [<type>]
|
||||||
|
|
||||||
|
|
||||||
|
Holes
|
||||||
|
- - -
|
||||||
|
|
||||||
|
Holes can be used for through-hole pins or for mechanical support.
|
||||||
|
In the former case, the hole must be placed inside a pad. Only one
|
||||||
|
hole per pad is allowed. Mechanical holes must be outside any pads.
|
||||||
|
|
||||||
|
Through-hole pads are always present on both sides of the board, i.e.,
|
||||||
|
when fped generates a KiCad module, the surface layers of a pad
|
||||||
|
containing a hole are propagated to the opposite side of the board.
|
||||||
|
|
||||||
|
Holes have the same shape as a rounded pad and their geometry is
|
||||||
|
defined in the same way:
|
||||||
|
|
||||||
|
hole <point-a> <point-b>
|
||||||
|
|
||||||
|
|
||||||
Measurements
|
Measurements
|
||||||
- - - - - -
|
- - - - - -
|
||||||
|
|
||||||
|
9
gui.html
9
gui.html
@ -222,6 +222,15 @@ Tools are used to add new elements and to manipulate existing ones.
|
|||||||
containing the pad. Move the mouse cursor to the first point, then
|
containing the pad. Move the mouse cursor to the first point, then
|
||||||
drag to the second point. The pad's name can be edited after selecting
|
drag to the second point. The pad's name can be edited after selecting
|
||||||
the pad.
|
the pad.
|
||||||
|
<DT><IMG src="manual/hole.png">
|
||||||
|
<DD> Add a hole. There are two purposes for holes:
|
||||||
|
<UL>
|
||||||
|
<LI> Pins of through-hole components. In this case, the hole has to be
|
||||||
|
inside a pad.
|
||||||
|
<LI> Mechanical support. In this case, the hole has to be outside any
|
||||||
|
pads.
|
||||||
|
</UL>
|
||||||
|
The construction of holes is the same as for pads.
|
||||||
<DT><IMG src="manual/line.png"> <IMG src="manual/rect.png">
|
<DT><IMG src="manual/line.png"> <IMG src="manual/rect.png">
|
||||||
<DD> Add a line or a rectangle. Similar to pads, lines and rectangles
|
<DD> Add a line or a rectangle. Similar to pads, lines and rectangles
|
||||||
are defined by two points. The width of the line can be edited after
|
are defined by two points. The width of the line can be edited after
|
||||||
|
86
hole.c
Normal file
86
hole.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* hole.c - Classify holes and connect them with pads
|
||||||
|
*
|
||||||
|
* Written 2010 by Werner Almesberger
|
||||||
|
* Copyright 2010 by Werner Almesberger
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "error.h"
|
||||||
|
#include "inst.h"
|
||||||
|
#include "overlap.h"
|
||||||
|
#include "hole.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int check_through_hole(struct inst *pad, struct inst *hole)
|
||||||
|
{
|
||||||
|
if (!overlap(pad, hole))
|
||||||
|
return 1;
|
||||||
|
if (!inside(hole, pad)) {
|
||||||
|
fail("hole (line %d) not completely inside "
|
||||||
|
"pad \"%s\" (line %d)", hole->obj->lineno,
|
||||||
|
pad->u.pad.name, pad->obj->lineno);
|
||||||
|
instantiation_error = pad->obj;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (hole->u.hole.pad) {
|
||||||
|
/*
|
||||||
|
* A hole can only be on several pads if the pads themselves
|
||||||
|
* overlap. We'll catch this error in refine_copper.
|
||||||
|
*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (pad->u.pad.hole) {
|
||||||
|
fail("pad \"%s\" (line %d) has multiple holes (lines %d, %d)",
|
||||||
|
pad->u.pad.name, pad->obj->lineno,
|
||||||
|
hole->obj->lineno, pad->u.pad.hole->obj->lineno);
|
||||||
|
instantiation_error = pad->obj;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pad->u.pad.hole = hole;
|
||||||
|
hole->u.hole.pad = pad;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int connect_holes(const struct pkg *pkg)
|
||||||
|
{
|
||||||
|
struct inst *pad, *hole;
|
||||||
|
|
||||||
|
for (pad = pkg->insts[ip_pad_copper]; pad; pad = pad->next)
|
||||||
|
for (hole = pkg->insts[ip_hole]; hole; hole = hole->next)
|
||||||
|
if (!check_through_hole(pad, hole))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void clear_links(const struct pkg *pkg)
|
||||||
|
{
|
||||||
|
struct inst *pad, *hole;
|
||||||
|
|
||||||
|
for (pad = pkg->insts[ip_pad_copper]; pad; pad = pad->next)
|
||||||
|
pad->u.pad.hole = NULL;
|
||||||
|
for (pad = pkg->insts[ip_pad_special]; pad; pad = pad->next)
|
||||||
|
pad->u.pad.hole = NULL;
|
||||||
|
for (hole = pkg->insts[ip_hole]; hole; hole = hole->next)
|
||||||
|
hole->u.hole.pad = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int link_holes(void)
|
||||||
|
{
|
||||||
|
const struct pkg *pkg;
|
||||||
|
|
||||||
|
for (pkg = pkgs; pkg; pkg = pkg->next) {
|
||||||
|
clear_links(pkg);
|
||||||
|
if (!connect_holes(pkg))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
18
hole.h
Normal file
18
hole.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* hole.h - Classify holes and connect them with pads
|
||||||
|
*
|
||||||
|
* Written 2010 by Werner Almesberger
|
||||||
|
* Copyright 2010 by Werner Almesberger
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HOLE_H
|
||||||
|
#define HOLE_H
|
||||||
|
|
||||||
|
int link_holes(void);
|
||||||
|
|
||||||
|
#endif /* !HOLE_H */
|
@ -7,12 +7,11 @@ A4
|
|||||||
Single
|
Single
|
||||||
-2
|
-2
|
||||||
1200 2
|
1200 2
|
||||||
6 3600 2400 6000 4800
|
|
||||||
1 3 0 8 0 7 45 -1 20 0.000 1 0.0000 4800 3600 600 600 4800 3600 5400 3600
|
1 3 0 8 0 7 45 -1 20 0.000 1 0.0000 4800 3600 600 600 4800 3600 5400 3600
|
||||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||||
3600 2400 6000 2400 6000 4800 3600 4800 3600 2400
|
3600 2400 6000 2400 6000 4800 3600 4800 3600 2400
|
||||||
2 1 0 5 0 7 50 -1 20 0.000 0 1 -1 0 0 2
|
2 1 0 5 0 7 50 -1 20 0.000 0 1 -1 0 0 2
|
||||||
3900 4500 5700 2700
|
4050 4350 5550 2850
|
||||||
2 1 0 5 0 7 50 -1 20 0.000 0 1 -1 0 0 2
|
2 1 0 5 0 7 50 -1 20 0.000 0 1 -1 0 0 2
|
||||||
3900 3900 5100 2700
|
3900 3900 5100 2700
|
||||||
2 1 0 5 0 7 50 -1 20 0.000 0 1 -1 0 0 2
|
2 1 0 5 0 7 50 -1 20 0.000 0 1 -1 0 0 2
|
||||||
@ -21,4 +20,3 @@ Single
|
|||||||
4500 4500 5700 3300
|
4500 4500 5700 3300
|
||||||
2 1 0 5 0 7 50 -1 20 0.000 0 1 -1 0 0 2
|
2 1 0 5 0 7 50 -1 20 0.000 0 1 -1 0 0 2
|
||||||
5100 4500 5700 3900
|
5100 4500 5700 3900
|
||||||
-6
|
|
||||||
|
2
inst.h
2
inst.h
@ -98,9 +98,11 @@ struct inst {
|
|||||||
char *name;
|
char *name;
|
||||||
struct coord other;
|
struct coord other;
|
||||||
layer_type layers; /* bit-set of layers */
|
layer_type layers; /* bit-set of layers */
|
||||||
|
struct inst *hole; /* through-hole or NULL */
|
||||||
} pad;
|
} pad;
|
||||||
struct {
|
struct {
|
||||||
struct coord other;
|
struct coord other;
|
||||||
|
struct inst *pad; /* through-hole pad of NULL */
|
||||||
} hole;
|
} hole;
|
||||||
struct {
|
struct {
|
||||||
unit_type r;
|
unit_type r;
|
||||||
|
3
obj.c
3
obj.c
@ -20,6 +20,7 @@
|
|||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "meas.h"
|
#include "meas.h"
|
||||||
#include "inst.h"
|
#include "inst.h"
|
||||||
|
#include "hole.h"
|
||||||
#include "layer.h"
|
#include "layer.h"
|
||||||
#include "delete.h"
|
#include "delete.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
@ -475,6 +476,8 @@ int instantiate(void)
|
|||||||
activate_found();
|
activate_found();
|
||||||
find_vec = NULL;
|
find_vec = NULL;
|
||||||
find_obj = NULL;
|
find_obj = NULL;
|
||||||
|
if (ok)
|
||||||
|
ok = link_holes();
|
||||||
if (ok)
|
if (ok)
|
||||||
ok = refine_layers();
|
ok = refine_layers();
|
||||||
if (ok)
|
if (ok)
|
||||||
|
46
overlap.c
46
overlap.c
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* overlap.c - Test for overlaps
|
* overlap.c - Test for overlaps
|
||||||
*
|
*
|
||||||
* Written 2009 by Werner Almesberger
|
* Written 2009, 2010 by Werner Almesberger
|
||||||
* Copyright 2009 by Werner Almesberger
|
* Copyright 2009, 2010 by Werner Almesberger
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -11,6 +11,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "coord.h"
|
#include "coord.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "inst.h"
|
#include "inst.h"
|
||||||
@ -18,7 +20,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @@@ result may be too optimistic if "b" is arounded pad.
|
* @@@ result may be too optimistic if "b" is a rounded pad
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int inside(const struct inst *a, const struct inst *b)
|
int inside(const struct inst *a, const struct inst *b)
|
||||||
@ -27,11 +29,29 @@ int inside(const struct inst *a, const struct inst *b)
|
|||||||
struct coord min_b, max_b;
|
struct coord min_b, max_b;
|
||||||
|
|
||||||
min_a = a->base;
|
min_a = a->base;
|
||||||
max_a = a->u.pad.other;
|
switch (a->obj->type) {
|
||||||
|
case ot_pad:
|
||||||
|
max_a = a->u.pad.other;
|
||||||
|
break;
|
||||||
|
case ot_hole:
|
||||||
|
max_a = a->u.hole.other;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
sort_coord(&min_a, &max_a);
|
sort_coord(&min_a, &max_a);
|
||||||
|
|
||||||
min_b = b->base;
|
min_b = b->base;
|
||||||
max_b = b->u.pad.other;
|
switch (b->obj->type) {
|
||||||
|
case ot_pad:
|
||||||
|
max_b = b->u.pad.other;
|
||||||
|
break;
|
||||||
|
case ot_hole:
|
||||||
|
max_b = b->u.hole.other;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
sort_coord(&min_b, &max_b);
|
sort_coord(&min_b, &max_b);
|
||||||
|
|
||||||
return min_a.x >= min_b.x && max_a.x <= max_b.x &&
|
return min_a.x >= min_b.x && max_a.x <= max_b.x &&
|
||||||
@ -142,15 +162,27 @@ static int test_overlap(const struct inst *a, const struct inst *b,
|
|||||||
{
|
{
|
||||||
struct coord min, max;
|
struct coord min, max;
|
||||||
unit_type h, w, r;
|
unit_type h, w, r;
|
||||||
|
int rounded;
|
||||||
|
|
||||||
min = a->base;
|
min = a->base;
|
||||||
max = a->u.pad.other;
|
switch (a->obj->type) {
|
||||||
|
case ot_pad:
|
||||||
|
max = a->u.pad.other;
|
||||||
|
rounded = a->obj->u.pad.rounded;
|
||||||
|
break;
|
||||||
|
case ot_hole:
|
||||||
|
max = a->u.hole.other;
|
||||||
|
rounded = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
sort_coord(&min, &max);
|
sort_coord(&min, &max);
|
||||||
|
|
||||||
h = max.y-min.y;
|
h = max.y-min.y;
|
||||||
w = max.x-min.x;
|
w = max.x-min.x;
|
||||||
|
|
||||||
if (!a->obj->u.pad.rounded)
|
if (!rounded)
|
||||||
return do_rect(b, other, min.x, min.y, w, h);
|
return do_rect(b, other, min.x, min.y, w, h);
|
||||||
|
|
||||||
if (h > w) {
|
if (h > w) {
|
||||||
|
34
postscript.c
34
postscript.c
@ -64,6 +64,8 @@
|
|||||||
#define PS_HATCH mm_to_units(0.1)
|
#define PS_HATCH mm_to_units(0.1)
|
||||||
#define PS_HATCH_LINE mm_to_units(0.015)
|
#define PS_HATCH_LINE mm_to_units(0.015)
|
||||||
|
|
||||||
|
#define PS_RIM_LINE mm_to_units(0.02)
|
||||||
|
|
||||||
#define PS_FONT_OUTLINE mm_to_units(0.025)
|
#define PS_FONT_OUTLINE mm_to_units(0.025)
|
||||||
|
|
||||||
#define PS_VEC_LINE mm_to_units(0.02)
|
#define PS_VEC_LINE mm_to_units(0.02)
|
||||||
@ -220,21 +222,19 @@ static void ps_pad(FILE *file, const struct inst *inst, int show_name)
|
|||||||
fprintf(file, " closepath gsave %s grestore stroke\n",
|
fprintf(file, " closepath gsave %s grestore stroke\n",
|
||||||
hatch(inst->u.pad.layers));
|
hatch(inst->u.pad.layers));
|
||||||
|
|
||||||
if (show_name)
|
if (show_name && !inst->u.pad.hole)
|
||||||
ps_pad_name(file, inst);
|
ps_pad_name(file, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ps_rpad(FILE *file, const struct inst *inst, int show_name)
|
static void ps_rounded_rect(FILE *file, struct coord a, struct coord b)
|
||||||
{
|
{
|
||||||
struct coord a = inst->base;
|
|
||||||
struct coord b = inst->u.pad.other;
|
|
||||||
unit_type h, w, r;
|
unit_type h, w, r;
|
||||||
|
|
||||||
sort_coord(&a, &b);
|
sort_coord(&a, &b);
|
||||||
h = b.y-a.y;
|
h = b.y-a.y;
|
||||||
w = b.x-a.x;
|
w = b.x-a.x;
|
||||||
fprintf(file, "0 setgray %d setlinewidth\n", PS_HATCH_LINE);
|
|
||||||
if (h > w) {
|
if (h > w) {
|
||||||
r = w/2;
|
r = w/2;
|
||||||
fprintf(file, " %d %d moveto\n", b.x, b.y-r);
|
fprintf(file, " %d %d moveto\n", b.x, b.y-r);
|
||||||
@ -248,14 +248,33 @@ static void ps_rpad(FILE *file, const struct inst *inst, int show_name)
|
|||||||
fprintf(file, " %d %d lineto\n", a.x+r, b.y);
|
fprintf(file, " %d %d lineto\n", a.x+r, b.y);
|
||||||
fprintf(file, " %d %d %d 90 270 arc\n", a.x+r, a.y+r, r);
|
fprintf(file, " %d %d %d 90 270 arc\n", a.x+r, a.y+r, r);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ps_rpad(FILE *file, const struct inst *inst, int show_name)
|
||||||
|
{
|
||||||
|
fprintf(file, "0 setgray %d setlinewidth\n", PS_HATCH_LINE);
|
||||||
|
ps_rounded_rect(file, inst->base, inst->u.pad.other);
|
||||||
fprintf(file, " closepath gsave %s grestore stroke\n",
|
fprintf(file, " closepath gsave %s grestore stroke\n",
|
||||||
hatch(inst->u.pad.layers));
|
hatch(inst->u.pad.layers));
|
||||||
|
|
||||||
if (show_name)
|
if (show_name && !inst->u.pad.hole)
|
||||||
ps_pad_name(file, inst);
|
ps_pad_name(file, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ps_hole(FILE *file, const struct inst *inst, int show_name)
|
||||||
|
{
|
||||||
|
fprintf(file, "1 setgray %d setlinewidth\n", PS_RIM_LINE);
|
||||||
|
ps_rounded_rect(file, inst->base, inst->u.hole.other);
|
||||||
|
fprintf(file, " closepath gsave fill grestore\n");
|
||||||
|
fprintf(file, " 0 setgray stroke\n");
|
||||||
|
|
||||||
|
if (show_name && inst->u.hole.pad)
|
||||||
|
ps_pad_name(file, inst->u.hole.pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ps_line(FILE *file, const struct inst *inst)
|
static void ps_line(FILE *file, const struct inst *inst)
|
||||||
{
|
{
|
||||||
struct coord a = inst->base;
|
struct coord a = inst->base;
|
||||||
@ -485,6 +504,9 @@ static void ps_foreground(FILE *file, enum inst_prio prio,
|
|||||||
else
|
else
|
||||||
ps_pad(file, inst, active_params.show_pad_names);
|
ps_pad(file, inst, active_params.show_pad_names);
|
||||||
break;
|
break;
|
||||||
|
case ip_hole:
|
||||||
|
ps_hole(file, inst, active_params.show_pad_names);
|
||||||
|
break;
|
||||||
case ip_vec:
|
case ip_vec:
|
||||||
if (active_params.show_stuff)
|
if (active_params.show_stuff)
|
||||||
ps_vec(file, inst);
|
ps_vec(file, inst);
|
||||||
|
Loading…
Reference in New Issue
Block a user