mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-24 09:07:31 +02:00
Added relaxation of pad overlap checking. Not GUI-settable yet.
- README, fpd.l, fpd.y: added directives "allow touch" and "allow overlap" to make overlap checking more permissive - dump.c (dump_allow, dump): generate "allow" directive - obj.h, obj.c (allow_overlap): added global variable for strictness of overlap checking - overlap.h, overlap.c (overlap, ...), layer.h, layer.c (refine_layers): strictness of overlap checking is passed as an argument - hole.c (check_through_hole), layer.h, layer.c (refine_copper), obj.c (instantiate): updated callers of "overlap" to provide "allow" argument git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5974 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
parent
b2b3a46119
commit
e6b2658a65
28
README
28
README
@ -106,7 +106,7 @@ The file has the following structure:
|
||||
frame definitions
|
||||
...
|
||||
package name
|
||||
unit
|
||||
setup
|
||||
objects
|
||||
...
|
||||
|
||||
@ -124,6 +124,14 @@ from the previous vector to (2mm, 2mm), and then make a line connecting
|
||||
the two points.
|
||||
|
||||
|
||||
Setup
|
||||
- - -
|
||||
|
||||
The setup section defines settings that affect the entire footprint.
|
||||
It is optional and can contain a "unit" directive and an "allow"
|
||||
directive.
|
||||
|
||||
|
||||
Units
|
||||
- - -
|
||||
|
||||
@ -154,6 +162,24 @@ When saving a footprint definition, the default unit is set to the
|
||||
unit set in the GUI.
|
||||
|
||||
|
||||
Allow
|
||||
- - -
|
||||
|
||||
fped normally disallows overlapping pads. This restriction can be
|
||||
relaxed with the "allow" directive.
|
||||
|
||||
allow touch
|
||||
|
||||
Allows pads touching but not having more than their border in common.
|
||||
|
||||
allow overlap
|
||||
|
||||
Do not check for overlaps at all.
|
||||
|
||||
If the "allow" directive is omitted, fped defaults to allowing
|
||||
neigher overlap nor touch.
|
||||
|
||||
|
||||
Vectors
|
||||
- - - -
|
||||
|
||||
|
19
dump.c
19
dump.c
@ -569,6 +569,23 @@ static void dump_unit(FILE *file)
|
||||
}
|
||||
|
||||
|
||||
static void dump_allow(FILE *file)
|
||||
{
|
||||
switch (allow_overlap) {
|
||||
case ao_none:
|
||||
break;
|
||||
case ao_touch:
|
||||
fprintf(file, "allow touch\n");
|
||||
break;
|
||||
case ao_any:
|
||||
fprintf(file, "allow overlap\n");
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void reverse_frames(FILE *file, struct frame *last)
|
||||
{
|
||||
if (last) {
|
||||
@ -589,6 +606,8 @@ int dump(FILE *file)
|
||||
reverse_frames(file, frames->next);
|
||||
fprintf(file, "package \"%s\"\n", pkg_name);
|
||||
dump_unit(file);
|
||||
dump_allow(file);
|
||||
fprintf(file, "\n");
|
||||
dump_frame(file, frames, "");
|
||||
|
||||
fflush(file);
|
||||
|
6
fpd.l
6
fpd.l
@ -61,6 +61,8 @@ void scan_values(const char *s)
|
||||
|
||||
/* keywords are only accepted at the beginning of a line */
|
||||
%s NOKEYWORD
|
||||
/* ALLOW is followed by special keywords (we could use NOKEYWORD as well) */
|
||||
%s ALLOW
|
||||
|
||||
NUM [0-9]+\.?[0-9]*
|
||||
SP [\t ]*
|
||||
@ -123,6 +125,10 @@ SP [\t ]*
|
||||
<INITIAL>"unit" { BEGIN(NOKEYWORD);
|
||||
return TOK_UNIT; }
|
||||
|
||||
<INITIAL>"allow" BEGIN(ALLOW);
|
||||
<ALLOW>"overlap" return TOK_ALLOW_OVERLAP;
|
||||
<ALLOW>"touch" return TOK_ALLOW_TOUCH;
|
||||
|
||||
<INITIAL>"%del" { BEGIN(NOKEYWORD);
|
||||
return TOK_DBG_DEL; }
|
||||
<INITIAL>"%move" { BEGIN(NOKEYWORD);
|
||||
|
27
fpd.y
27
fpd.y
@ -459,6 +459,7 @@ static int dbg_meas(const char *name)
|
||||
%token TOK_NEXT TOK_NEXT_INVERTED TOK_MAX TOK_MAX_INVERTED
|
||||
%token TOK_DBG_DEL TOK_DBG_MOVE TOK_DBG_FRAME TOK_DBG_PRINT
|
||||
%token TOK_DBG_DUMP TOK_DBG_EXIT TOK_DBG_TSORT TOK_DBG_MEAS
|
||||
%token TOK_ALLOW_OVERLAP TOK_ALLOW_TOUCH
|
||||
|
||||
%token <num> NUMBER
|
||||
%token <str> STRING
|
||||
@ -508,8 +509,8 @@ all:
|
||||
;
|
||||
|
||||
fpd:
|
||||
frame_defs part_name opt_unit opt_frame_items opt_measurements
|
||||
| frame_defs unit opt_frame_items opt_measurements
|
||||
frame_defs part_name opt_setup opt_frame_items opt_measurements
|
||||
| frame_defs setup opt_frame_items opt_measurements
|
||||
| frame_defs frame_items opt_measurements
|
||||
| frame_defs opt_measurements
|
||||
;
|
||||
@ -532,8 +533,15 @@ part_name:
|
||||
}
|
||||
;
|
||||
|
||||
opt_unit:
|
||||
| unit
|
||||
opt_setup:
|
||||
| setup
|
||||
;
|
||||
|
||||
setup:
|
||||
unit
|
||||
| allow
|
||||
| unit allow
|
||||
| allow unit
|
||||
;
|
||||
|
||||
unit:
|
||||
@ -552,6 +560,17 @@ unit:
|
||||
}
|
||||
;
|
||||
|
||||
allow:
|
||||
TOK_ALLOW_TOUCH
|
||||
{
|
||||
allow_overlap = ao_touch;
|
||||
}
|
||||
| TOK_ALLOW_OVERLAP
|
||||
{
|
||||
allow_overlap = ao_any;
|
||||
}
|
||||
;
|
||||
|
||||
frame_defs:
|
||||
| frame_defs frame_def
|
||||
;
|
||||
|
2
hole.c
2
hole.c
@ -19,7 +19,7 @@
|
||||
|
||||
static int check_through_hole(struct inst *pad, struct inst *hole)
|
||||
{
|
||||
if (!overlap(pad, hole))
|
||||
if (!overlap(pad, hole, ao_none))
|
||||
return 1;
|
||||
if (!inside(hole, pad)) {
|
||||
fail("hole (line %d) not completely inside "
|
||||
|
11
layer.c
11
layer.c
@ -113,7 +113,8 @@ static int refine_overlapping(struct inst *copper, struct inst *other)
|
||||
}
|
||||
|
||||
|
||||
static int refine_copper(const struct pkg *pkg_copper, struct inst *copper)
|
||||
static int refine_copper(const struct pkg *pkg_copper, struct inst *copper,
|
||||
enum allow_overlap allow)
|
||||
{
|
||||
const struct pkg *pkg;
|
||||
struct inst *other;
|
||||
@ -126,7 +127,7 @@ static int refine_copper(const struct pkg *pkg_copper, struct inst *copper)
|
||||
continue;
|
||||
for (other = pkg->insts[ip_pad_copper]; other;
|
||||
other = other->next)
|
||||
if (copper != other && overlap(copper, other)) {
|
||||
if (copper != other && overlap(copper, other, allow)) {
|
||||
fail("overlapping copper pads "
|
||||
"(\"%s\" line %d, \"%s\" line %d)",
|
||||
copper->u.pad.name, copper->obj->lineno,
|
||||
@ -136,7 +137,7 @@ static int refine_copper(const struct pkg *pkg_copper, struct inst *copper)
|
||||
}
|
||||
for (other = pkg->insts[ip_pad_special]; other;
|
||||
other = other->next)
|
||||
if (overlap(copper, other))
|
||||
if (overlap(copper, other, ao_none))
|
||||
if (!refine_overlapping(copper, other))
|
||||
return 0;
|
||||
}
|
||||
@ -155,7 +156,7 @@ static void mirror_layers(layer_type *layers)
|
||||
}
|
||||
|
||||
|
||||
int refine_layers(void)
|
||||
int refine_layers(enum allow_overlap allow)
|
||||
{
|
||||
const struct pkg *pkg;
|
||||
struct inst *copper;
|
||||
@ -163,7 +164,7 @@ int refine_layers(void)
|
||||
for (pkg = pkgs; pkg; pkg = pkg->next)
|
||||
for (copper = pkg->insts[ip_pad_copper]; copper;
|
||||
copper = copper->next) {
|
||||
if (!refine_copper(pkg, copper))
|
||||
if (!refine_copper(pkg, copper, allow))
|
||||
return 0;
|
||||
if (copper->u.pad.hole)
|
||||
mirror_layers(&copper->u.pad.layers);
|
||||
|
4
layer.h
4
layer.h
@ -15,6 +15,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "overlap.h"
|
||||
|
||||
|
||||
typedef uint32_t layer_type;
|
||||
|
||||
@ -75,6 +77,6 @@ enum pad_type layers_to_pad_type(layer_type layers);
|
||||
|
||||
layer_type mech_hole_layers(void);
|
||||
|
||||
int refine_layers(void);
|
||||
int refine_layers(enum allow_overlap allow);
|
||||
|
||||
#endif /* !LAYER_H */
|
||||
|
4
obj.c
4
obj.c
@ -22,6 +22,7 @@
|
||||
#include "meas.h"
|
||||
#include "inst.h"
|
||||
#include "hole.h"
|
||||
#include "overlap.h"
|
||||
#include "layer.h"
|
||||
#include "delete.h"
|
||||
#include "obj.h"
|
||||
@ -37,6 +38,7 @@ char *pkg_name = NULL;
|
||||
struct frame *frames = NULL;
|
||||
struct frame *active_frame = NULL;
|
||||
void *instantiation_error = NULL;
|
||||
enum allow_overlap allow_overlap = ao_none;
|
||||
|
||||
|
||||
static struct bitset *frame_set; /* frames visited in "call chain" */
|
||||
@ -498,7 +500,7 @@ int instantiate(void)
|
||||
if (ok)
|
||||
ok = link_holes();
|
||||
if (ok)
|
||||
ok = refine_layers();
|
||||
ok = refine_layers(allow_overlap);
|
||||
if (ok)
|
||||
ok = instantiate_meas(n_frames);
|
||||
if (ok)
|
||||
|
2
obj.h
2
obj.h
@ -20,6 +20,7 @@
|
||||
#include "expr.h"
|
||||
#include "coord.h"
|
||||
#include "meas.h"
|
||||
#include "overlap.h"
|
||||
#include "layer.h"
|
||||
|
||||
|
||||
@ -242,6 +243,7 @@ extern char *pkg_name; /* anonymous common package first */
|
||||
extern struct frame *frames; /* root frame first */
|
||||
extern struct frame *active_frame;
|
||||
extern void *instantiation_error;
|
||||
extern enum allow_overlap allow_overlap;
|
||||
|
||||
|
||||
struct inst;
|
||||
|
71
overlap.c
71
overlap.c
@ -71,15 +71,23 @@ struct shape {
|
||||
|
||||
|
||||
static int circle_circle_overlap(struct coord c1, unit_type r1,
|
||||
struct coord c2, unit_type r2)
|
||||
struct coord c2, unit_type r2, enum allow_overlap allow)
|
||||
{
|
||||
if (allow == ao_touch)
|
||||
return dist_point(c1, c2) < r1+r2;
|
||||
return dist_point(c1, c2) <= r1+r2;
|
||||
}
|
||||
|
||||
|
||||
static int circle_rect_overlap(struct coord c, unit_type r,
|
||||
struct coord min, struct coord max)
|
||||
struct coord min, struct coord max, enum allow_overlap allow)
|
||||
{
|
||||
if (allow == ao_touch) {
|
||||
if (c.x <= min.x-r || c.x >= max.x+r)
|
||||
return 0;
|
||||
if (c.y <= min.y-r || c.y >= max.y+r)
|
||||
return 0;
|
||||
}
|
||||
if (c.x < min.x-r || c.x > max.x+r)
|
||||
return 0;
|
||||
if (c.y < min.y-r || c.y > max.y+r)
|
||||
@ -89,8 +97,14 @@ static int circle_rect_overlap(struct coord c, unit_type r,
|
||||
|
||||
|
||||
static int rect_rect_overlap(struct coord min1, struct coord max1,
|
||||
struct coord min2, struct coord max2)
|
||||
struct coord min2, struct coord max2, enum allow_overlap allow)
|
||||
{
|
||||
if (allow == ao_touch) {
|
||||
if (max1.x <= min2.x || max2.x <= min1.x)
|
||||
return 0;
|
||||
if (max1.y <= min2.y || max2.y <= min1.y)
|
||||
return 0;
|
||||
}
|
||||
if (max1.x < min2.x || max2.x < min1.x)
|
||||
return 0;
|
||||
if (max1.y < min2.y || max2.y < min1.y)
|
||||
@ -99,15 +113,18 @@ static int rect_rect_overlap(struct coord min1, struct coord max1,
|
||||
}
|
||||
|
||||
|
||||
static int shapes_overlap(const struct shape *a, const struct shape *b)
|
||||
static int shapes_overlap(const struct shape *a, const struct shape *b,
|
||||
enum allow_overlap allow)
|
||||
{
|
||||
if (a->circle && !b->circle)
|
||||
return shapes_overlap(b, a);
|
||||
return shapes_overlap(b, a, allow);
|
||||
if (a->circle) /* b must be circle, too */
|
||||
return circle_circle_overlap(a->center, a->r, b->center, b->r);
|
||||
return circle_circle_overlap(a->center, a->r, b->center, b->r,
|
||||
allow);
|
||||
if (b->circle) /* a must be rect */
|
||||
return circle_rect_overlap(b->center, b->r, a->min, a->max);
|
||||
return rect_rect_overlap(a->min, a->max, b->min, b->max);
|
||||
return circle_rect_overlap(b->center, b->r, a->min, a->max,
|
||||
allow);
|
||||
return rect_rect_overlap(a->min, a->max, b->min, b->max, allow);
|
||||
}
|
||||
|
||||
|
||||
@ -115,11 +132,11 @@ static int shapes_overlap(const struct shape *a, const struct shape *b)
|
||||
|
||||
|
||||
static int test_overlap(const struct inst *a, const struct inst *b,
|
||||
const struct shape *other);
|
||||
const struct shape *other, enum allow_overlap allow);
|
||||
|
||||
|
||||
static int do_circle(const struct inst *next, const struct shape *other,
|
||||
unit_type x, unit_type y, unit_type r)
|
||||
unit_type x, unit_type y, unit_type r, enum allow_overlap allow)
|
||||
{
|
||||
struct shape shape = {
|
||||
.circle = 1,
|
||||
@ -131,13 +148,14 @@ static int do_circle(const struct inst *next, const struct shape *other,
|
||||
};
|
||||
|
||||
if (next)
|
||||
return test_overlap(next, NULL, &shape);
|
||||
return shapes_overlap(other, &shape);
|
||||
return test_overlap(next, NULL, &shape, allow);
|
||||
return shapes_overlap(other, &shape, allow);
|
||||
}
|
||||
|
||||
|
||||
static int do_rect(const struct inst *next, const struct shape *other,
|
||||
unit_type x, unit_type y, unit_type w, unit_type h)
|
||||
unit_type x, unit_type y, unit_type w, unit_type h,
|
||||
enum allow_overlap allow)
|
||||
{
|
||||
struct shape shape = {
|
||||
.circle = 0,
|
||||
@ -152,13 +170,13 @@ static int do_rect(const struct inst *next, const struct shape *other,
|
||||
};
|
||||
|
||||
if (next)
|
||||
return test_overlap(next, NULL, &shape);
|
||||
return shapes_overlap(other, &shape);
|
||||
return test_overlap(next, NULL, &shape, allow);
|
||||
return shapes_overlap(other, &shape, allow);
|
||||
}
|
||||
|
||||
|
||||
static int test_overlap(const struct inst *a, const struct inst *b,
|
||||
const struct shape *other)
|
||||
const struct shape *other, enum allow_overlap allow)
|
||||
{
|
||||
struct coord min, max;
|
||||
unit_type h, w, r;
|
||||
@ -183,23 +201,26 @@ static int test_overlap(const struct inst *a, const struct inst *b,
|
||||
w = max.x-min.x;
|
||||
|
||||
if (!rounded)
|
||||
return do_rect(b, other, min.x, min.y, w, h);
|
||||
return do_rect(b, other, min.x, min.y, w, h, allow);
|
||||
|
||||
if (h > w) {
|
||||
r = w/2;
|
||||
return do_circle(b, other, min.x+r, max.y-r, r) ||
|
||||
do_rect(b, other, min.x, min.y+r, w, h-2*r) ||
|
||||
do_circle(b, other, min.x+r, min.y+r, r);
|
||||
return do_circle(b, other, min.x+r, max.y-r, r, allow) ||
|
||||
do_rect(b, other, min.x, min.y+r, w, h-2*r, allow) ||
|
||||
do_circle(b, other, min.x+r, min.y+r, r, allow);
|
||||
} else {
|
||||
r = h/2;
|
||||
return do_circle(b, other, min.x+r, min.y+r, r) ||
|
||||
do_rect(b, other, min.x+r, min.y, w-2*r, h) ||
|
||||
do_circle(b, other, max.x-r, min.y+r, r);
|
||||
return do_circle(b, other, min.x+r, min.y+r, r, allow) ||
|
||||
do_rect(b, other, min.x+r, min.y, w-2*r, h, allow) ||
|
||||
do_circle(b, other, max.x-r, min.y+r, r, allow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int overlap(const struct inst *a, const struct inst *b)
|
||||
int overlap(const struct inst *a, const struct inst *b,
|
||||
enum allow_overlap allow)
|
||||
{
|
||||
return test_overlap(a, b, NULL);
|
||||
if (allow == ao_any)
|
||||
return 0;
|
||||
return test_overlap(a, b, NULL, allow);
|
||||
}
|
||||
|
21
overlap.h
21
overlap.h
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* overlap.h - Test for overlaps
|
||||
*
|
||||
* Written 2009 by Werner Almesberger
|
||||
* Copyright 2009 by Werner Almesberger
|
||||
* Written 2009, 2010 by Werner Almesberger
|
||||
* Copyright 2009, 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
|
||||
@ -13,7 +13,19 @@
|
||||
#ifndef OVERLAP_H
|
||||
#define OVERLAP_H
|
||||
|
||||
#include "inst.h"
|
||||
|
||||
enum allow_overlap {
|
||||
ao_none,
|
||||
ao_touch,
|
||||
ao_any,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Avoid inst.h -> layer.h -> overlay.h -> inst.h loop
|
||||
*/
|
||||
|
||||
struct inst;
|
||||
|
||||
|
||||
/*
|
||||
@ -27,6 +39,7 @@ int inside(const struct inst *a, const struct inst *b);
|
||||
* "overlap" returns 1 if "a" and "b" have at least one point in common.
|
||||
*/
|
||||
|
||||
int overlap(const struct inst *a, const struct inst *b);
|
||||
int overlap(const struct inst *a, const struct inst *b,
|
||||
enum allow_overlap allow);
|
||||
|
||||
#endif /* !OVERLAP_H */
|
||||
|
Loading…
Reference in New Issue
Block a user