mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-12-22 18:15:32 +02:00
Holes can now also be output as KiCad modules.
- gui_style.c (gc_rim): slightly increased brightness when inactive - kicad.c (kicad_pad): move coordinate transform to new function kicad_centric - kicad.c: added pads with holes and mechanical holes - inst.h (struct inst.u.hole), inst.c (inst_hole): added "layers" field, like for pads - layer.c (LAYER_COPPER, LAYER_PASTE, LAYER_MASK): renamed to LAYER_*_TOP and added macros for corresponding bottom layers - layer.c (refine_layers): mirror top layers of through-hole pads - layer.h, layer.c (mech_hole_layers): return the layer set for mechanical layers git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5941 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
parent
6db067a90f
commit
e047cc074d
@ -71,7 +71,7 @@ void gui_setup_style(GdkDrawable *drawable)
|
||||
style(gc_pad_mask, "#000040", "#0000ff", "#ffff80", 2);
|
||||
style(gc_ptext, "#404040", "#ffffff", "#ffffff", 1);
|
||||
style(gc_hole, "#000000", "#000000", "#000000", 0);
|
||||
style(gc_rim, "#202020", "#606060", "#ffff80", 3);
|
||||
style(gc_rim, "#303030", "#606060", "#ffff80", 3);
|
||||
style(gc_meas, "#280040", "#ff00ff", "#ffff80", 1);
|
||||
style(gc_frame, "#005000", "#009000", "#ffff80", 1);
|
||||
|
||||
|
1
inst.c
1
inst.c
@ -933,6 +933,7 @@ int inst_hole(struct obj *obj, struct coord a, struct coord b)
|
||||
inst = add_inst(&hole_ops, ip_hole, a);
|
||||
inst->obj = obj;
|
||||
inst->u.hole.other = b;
|
||||
inst->u.pad.layers = mech_hole_layers();
|
||||
find_inst(inst);
|
||||
update_bbox(&inst->bbox, b);
|
||||
propagate_bbox(inst);
|
||||
|
1
inst.h
1
inst.h
@ -102,6 +102,7 @@ struct inst {
|
||||
} pad;
|
||||
struct {
|
||||
struct coord other;
|
||||
layer_type layers; /* bit-set of layers (mech only) */
|
||||
struct inst *pad; /* through-hole pad of NULL */
|
||||
} hole;
|
||||
struct {
|
||||
|
91
kicad.c
91
kicad.c
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* kicad.c - Dump objects in the KiCad board/module format
|
||||
*
|
||||
* 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
|
||||
@ -20,15 +20,22 @@
|
||||
#include "kicad.h"
|
||||
|
||||
|
||||
static void kicad_pad(FILE *file, const struct inst *inst)
|
||||
static unit_type zeroize(unit_type n)
|
||||
{
|
||||
return n == -1 || n == 1 ? 0 : n;
|
||||
}
|
||||
|
||||
|
||||
static void kicad_centric(struct coord a, struct coord b,
|
||||
struct coord *center, struct coord *size)
|
||||
{
|
||||
struct coord min, max;
|
||||
unit_type tmp;
|
||||
|
||||
min.x = units_to_kicad(inst->base.x);
|
||||
min.y = units_to_kicad(inst->base.y);
|
||||
max.x = units_to_kicad(inst->u.pad.other.x);
|
||||
max.y = units_to_kicad(inst->u.pad.other.y);
|
||||
min.x = units_to_kicad(a.x);
|
||||
min.y = units_to_kicad(a.y);
|
||||
max.x = units_to_kicad(b.x);
|
||||
max.y = units_to_kicad(b.y);
|
||||
|
||||
if (min.x > max.x) {
|
||||
tmp = min.x;
|
||||
@ -41,6 +48,40 @@ static void kicad_pad(FILE *file, const struct inst *inst)
|
||||
max.y = tmp;
|
||||
}
|
||||
|
||||
size->x = max.x-min.x;
|
||||
size->y = max.y-min.y;
|
||||
center->x = (min.x+max.x)/2;
|
||||
center->y = -(min.y+max.y)/2;
|
||||
}
|
||||
|
||||
|
||||
static void do_drill(FILE *file, const struct inst *pad, struct coord *ref)
|
||||
{
|
||||
const struct inst *hole = pad->u.pad.hole;
|
||||
struct coord center, size;
|
||||
|
||||
if (!hole)
|
||||
return;
|
||||
|
||||
kicad_centric(hole->base, hole->u.hole.other, ¢er, &size);
|
||||
|
||||
/* Allow for rounding errors */
|
||||
|
||||
fprintf(file, "Dr %d %d %d", size.x,
|
||||
-zeroize(center.x-ref->x), -zeroize(center.y-ref->y));
|
||||
if (size.x < size.y-1 || size.x > size.y+1)
|
||||
fprintf(file, " O %d %d", size.x, size.y);
|
||||
fprintf(file, "\n");
|
||||
*ref = center;
|
||||
}
|
||||
|
||||
|
||||
static void kicad_pad(FILE *file, const struct inst *inst)
|
||||
{
|
||||
struct coord center, size;
|
||||
|
||||
kicad_centric(inst->base, inst->u.pad.other, ¢er, &size);
|
||||
|
||||
fprintf(file, "$PAD\n");
|
||||
|
||||
/*
|
||||
@ -48,22 +89,49 @@ static void kicad_pad(FILE *file, const struct inst *inst)
|
||||
*/
|
||||
fprintf(file, "Sh \"%s\" %c %d %d 0 0 0\n",
|
||||
inst->u.pad.name, inst->obj->u.pad.rounded ? 'O' : 'R',
|
||||
max.x-min.x, max.y-min.y);
|
||||
size.x, size.y);
|
||||
|
||||
/*
|
||||
* Drill hole
|
||||
*/
|
||||
do_drill(file, inst, ¢er);
|
||||
|
||||
/*
|
||||
* Attributes: pad type, N, layer mask
|
||||
*/
|
||||
fprintf(file, "At SMD N %8.8X\n", (unsigned) inst->u.pad.layers);
|
||||
fprintf(file, "At %s N %8.8X\n",
|
||||
inst->u.pad.hole ? "STD" : "SMD", (unsigned) inst->u.pad.layers);
|
||||
|
||||
/*
|
||||
* Position: Xpos, Ypos
|
||||
*/
|
||||
fprintf(file, "Po %d %d\n", (min.x+max.x)/2, -(min.y+max.y)/2);
|
||||
fprintf(file, "Po %d %d\n", center.x, center.y);
|
||||
|
||||
fprintf(file, "$EndPAD\n");
|
||||
}
|
||||
|
||||
|
||||
static void kicad_hole(FILE *file, const struct inst *inst)
|
||||
{
|
||||
struct coord center, size;
|
||||
|
||||
if (inst->u.hole.pad)
|
||||
return;
|
||||
kicad_centric(inst->base, inst->u.hole.other, ¢er, &size);
|
||||
fprintf(file, "$PAD\n");
|
||||
if (size.x < size.y-1 || size.x > size.y+1) {
|
||||
fprintf(file, "Sh \"HOLE\" O %d %d 0 0 0\n", size.x, size.y);
|
||||
fprintf(file, "Dr %d 0 0 O %d %d\n", size.x, size.x, size.y);
|
||||
} else {
|
||||
fprintf(file, "Sh \"HOLE\" C %d %d 0 0 0\n", size.x, size.x);
|
||||
fprintf(file, "Dr %d 0 0\n", size.x);
|
||||
}
|
||||
fprintf(file, "At HOLE N %8.8X\n", (unsigned) inst->u.hole.layers);
|
||||
fprintf(file, "Po %d %d\n", center.x, center.y);
|
||||
fprintf(file, "$EndPAD\n");
|
||||
}
|
||||
|
||||
|
||||
static void kicad_line(FILE *file, const struct inst *inst)
|
||||
{
|
||||
/*
|
||||
@ -152,6 +220,9 @@ static void kicad_inst(FILE *file, enum inst_prio prio, const struct inst *inst)
|
||||
case ip_pad_special:
|
||||
kicad_pad(file, inst);
|
||||
break;
|
||||
case ip_hole:
|
||||
kicad_hole(file, inst);
|
||||
break;
|
||||
case ip_line:
|
||||
kicad_line(file, inst);
|
||||
break;
|
||||
|
63
layer.c
63
layer.c
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* layer.c - PCB layers on a pad
|
||||
*
|
||||
* 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
|
||||
@ -30,9 +30,12 @@
|
||||
* Shorthands for the layers we use in a general sense.
|
||||
*/
|
||||
|
||||
#define LAYER_COPPER (1 << layer_top)
|
||||
#define LAYER_PASTE (1 << layer_paste_top)
|
||||
#define LAYER_MASK (1 << layer_mask_top)
|
||||
#define LAYER_COPPER_TOP (1 << layer_top)
|
||||
#define LAYER_PASTE_TOP (1 << layer_paste_top)
|
||||
#define LAYER_MASK_TOP (1 << layer_mask_top)
|
||||
#define LAYER_COPPER_BOTTOM (1 << layer_bottom)
|
||||
#define LAYER_PASTE_BOTTOM (1 << layer_paste_bottom)
|
||||
#define LAYER_MASK_BOTTOM (1 << layer_mask_bottom)
|
||||
|
||||
|
||||
/* ----- Conversion between pad types and layer sets ----------------------- */
|
||||
@ -44,16 +47,16 @@ layer_type pad_type_to_layers(enum pad_type type)
|
||||
|
||||
switch (type) {
|
||||
case pt_normal:
|
||||
layers = LAYER_PASTE;
|
||||
layers = LAYER_PASTE_TOP;
|
||||
/* fall through */
|
||||
case pt_bare:
|
||||
layers |= LAYER_COPPER | LAYER_MASK;
|
||||
layers |= LAYER_COPPER_TOP | LAYER_MASK_TOP;
|
||||
break;
|
||||
case pt_paste:
|
||||
layers = LAYER_PASTE;
|
||||
layers = LAYER_PASTE_TOP;
|
||||
break;
|
||||
case pt_mask:
|
||||
layers = LAYER_MASK;
|
||||
layers = LAYER_MASK_TOP;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
@ -64,27 +67,37 @@ layer_type pad_type_to_layers(enum pad_type type)
|
||||
|
||||
enum pad_type layers_to_pad_type(layer_type layers)
|
||||
{
|
||||
if (layers & LAYER_COPPER) {
|
||||
if (layers & LAYER_PASTE)
|
||||
if (layers & LAYER_COPPER_TOP) {
|
||||
if (layers & LAYER_PASTE_TOP)
|
||||
return pt_normal;
|
||||
return pt_bare;
|
||||
} else {
|
||||
if (layers & LAYER_PASTE)
|
||||
if (layers & LAYER_PASTE_TOP)
|
||||
return pt_paste;
|
||||
if (layers & LAYER_MASK)
|
||||
if (layers & LAYER_MASK_TOP)
|
||||
return pt_mask;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ----- layers in mechanical holes ---------------------------------------- */
|
||||
|
||||
|
||||
layer_type mech_hole_layers(void)
|
||||
{
|
||||
return LAYER_PASTE_TOP | LAYER_PASTE_BOTTOM |
|
||||
LAYER_MASK_TOP | LAYER_MASK_BOTTOM;
|
||||
}
|
||||
|
||||
|
||||
/* ----- Refine layers after instantiation --------------------------------- */
|
||||
|
||||
|
||||
static int refine_overlapping(struct inst *copper, struct inst *other)
|
||||
{
|
||||
if (other->u.pad.layers & LAYER_PASTE) {
|
||||
copper->u.pad.layers &= ~LAYER_PASTE;
|
||||
if (other->u.pad.layers & LAYER_PASTE_TOP) {
|
||||
copper->u.pad.layers &= ~LAYER_PASTE_TOP;
|
||||
if (!inside(other, copper)) {
|
||||
fail("solder paste without copper underneath "
|
||||
"(\"%s\" line %d, \"%s\" line %d)",
|
||||
@ -94,8 +107,8 @@ static int refine_overlapping(struct inst *copper, struct inst *other)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (other->u.pad.layers & LAYER_MASK)
|
||||
copper->u.pad.layers &= ~LAYER_MASK;
|
||||
if (other->u.pad.layers & LAYER_MASK_TOP)
|
||||
copper->u.pad.layers &= ~LAYER_MASK_TOP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -131,6 +144,17 @@ static int refine_copper(const struct pkg *pkg_copper, struct inst *copper)
|
||||
}
|
||||
|
||||
|
||||
static void mirror_layers(layer_type *layers)
|
||||
{
|
||||
if (*layers & LAYER_COPPER_TOP)
|
||||
*layers |= LAYER_COPPER_BOTTOM;
|
||||
if (*layers & LAYER_PASTE_TOP)
|
||||
*layers |= LAYER_PASTE_BOTTOM;
|
||||
if (*layers & LAYER_MASK_TOP)
|
||||
*layers |= LAYER_MASK_BOTTOM;
|
||||
}
|
||||
|
||||
|
||||
int refine_layers(void)
|
||||
{
|
||||
const struct pkg *pkg;
|
||||
@ -138,8 +162,11 @@ int refine_layers(void)
|
||||
|
||||
for (pkg = pkgs; pkg; pkg = pkg->next)
|
||||
for (copper = pkg->insts[ip_pad_copper]; copper;
|
||||
copper = copper->next)
|
||||
copper = copper->next) {
|
||||
if (!refine_copper(pkg, copper))
|
||||
return 0;
|
||||
if (copper->u.pad.hole)
|
||||
mirror_layers(&copper->u.pad.layers);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
6
layer.h
6
layer.h
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* layer.h - PCB layers on a pad
|
||||
*
|
||||
* 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
|
||||
@ -73,6 +73,8 @@ enum pad_type {
|
||||
layer_type pad_type_to_layers(enum pad_type type);
|
||||
enum pad_type layers_to_pad_type(layer_type layers);
|
||||
|
||||
layer_type mech_hole_layers(void);
|
||||
|
||||
int refine_layers(void);
|
||||
|
||||
#endif /* !LAYER_H */
|
||||
|
Loading…
Reference in New Issue
Block a user