1
0
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:
werner 2010-04-25 15:27:27 +00:00
parent 6db067a90f
commit e047cc074d
6 changed files with 133 additions and 31 deletions

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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, &center, &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, &center, &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, &center);
/*
* 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, &center, &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
View File

@ -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;
}

View File

@ -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 */