1
0
mirror of git://projects.qi-hardware.com/fped.git synced 2024-11-25 17:55:00 +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_pad_mask, "#000040", "#0000ff", "#ffff80", 2);
style(gc_ptext, "#404040", "#ffffff", "#ffffff", 1); style(gc_ptext, "#404040", "#ffffff", "#ffffff", 1);
style(gc_hole, "#000000", "#000000", "#000000", 0); 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_meas, "#280040", "#ff00ff", "#ffff80", 1);
style(gc_frame, "#005000", "#009000", "#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 = add_inst(&hole_ops, ip_hole, a);
inst->obj = obj; inst->obj = obj;
inst->u.hole.other = b; inst->u.hole.other = b;
inst->u.pad.layers = mech_hole_layers();
find_inst(inst); find_inst(inst);
update_bbox(&inst->bbox, b); update_bbox(&inst->bbox, b);
propagate_bbox(inst); propagate_bbox(inst);

1
inst.h
View File

@ -102,6 +102,7 @@ struct inst {
} pad; } pad;
struct { struct {
struct coord other; struct coord other;
layer_type layers; /* bit-set of layers (mech only) */
struct inst *pad; /* through-hole pad of NULL */ struct inst *pad; /* through-hole pad of NULL */
} hole; } hole;
struct { struct {

91
kicad.c
View File

@ -1,8 +1,8 @@
/* /*
* kicad.c - Dump objects in the KiCad board/module format * kicad.c - Dump objects in the KiCad board/module format
* *
* 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
@ -20,15 +20,22 @@
#include "kicad.h" #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; struct coord min, max;
unit_type tmp; unit_type tmp;
min.x = units_to_kicad(inst->base.x); min.x = units_to_kicad(a.x);
min.y = units_to_kicad(inst->base.y); min.y = units_to_kicad(a.y);
max.x = units_to_kicad(inst->u.pad.other.x); max.x = units_to_kicad(b.x);
max.y = units_to_kicad(inst->u.pad.other.y); max.y = units_to_kicad(b.y);
if (min.x > max.x) { if (min.x > max.x) {
tmp = min.x; tmp = min.x;
@ -41,6 +48,40 @@ static void kicad_pad(FILE *file, const struct inst *inst)
max.y = tmp; 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"); 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", fprintf(file, "Sh \"%s\" %c %d %d 0 0 0\n",
inst->u.pad.name, inst->obj->u.pad.rounded ? 'O' : 'R', 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 * 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 * 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"); 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) 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: case ip_pad_special:
kicad_pad(file, inst); kicad_pad(file, inst);
break; break;
case ip_hole:
kicad_hole(file, inst);
break;
case ip_line: case ip_line:
kicad_line(file, inst); kicad_line(file, inst);
break; break;

63
layer.c
View File

@ -1,8 +1,8 @@
/* /*
* layer.c - PCB layers on a pad * layer.c - PCB layers on a pad
* *
* 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
@ -30,9 +30,12 @@
* Shorthands for the layers we use in a general sense. * Shorthands for the layers we use in a general sense.
*/ */
#define LAYER_COPPER (1 << layer_top) #define LAYER_COPPER_TOP (1 << layer_top)
#define LAYER_PASTE (1 << layer_paste_top) #define LAYER_PASTE_TOP (1 << layer_paste_top)
#define LAYER_MASK (1 << layer_mask_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 ----------------------- */ /* ----- Conversion between pad types and layer sets ----------------------- */
@ -44,16 +47,16 @@ layer_type pad_type_to_layers(enum pad_type type)
switch (type) { switch (type) {
case pt_normal: case pt_normal:
layers = LAYER_PASTE; layers = LAYER_PASTE_TOP;
/* fall through */ /* fall through */
case pt_bare: case pt_bare:
layers |= LAYER_COPPER | LAYER_MASK; layers |= LAYER_COPPER_TOP | LAYER_MASK_TOP;
break; break;
case pt_paste: case pt_paste:
layers = LAYER_PASTE; layers = LAYER_PASTE_TOP;
break; break;
case pt_mask: case pt_mask:
layers = LAYER_MASK; layers = LAYER_MASK_TOP;
break; break;
default: default:
abort(); 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) enum pad_type layers_to_pad_type(layer_type layers)
{ {
if (layers & LAYER_COPPER) { if (layers & LAYER_COPPER_TOP) {
if (layers & LAYER_PASTE) if (layers & LAYER_PASTE_TOP)
return pt_normal; return pt_normal;
return pt_bare; return pt_bare;
} else { } else {
if (layers & LAYER_PASTE) if (layers & LAYER_PASTE_TOP)
return pt_paste; return pt_paste;
if (layers & LAYER_MASK) if (layers & LAYER_MASK_TOP)
return pt_mask; return pt_mask;
abort(); 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 --------------------------------- */ /* ----- Refine layers after instantiation --------------------------------- */
static int refine_overlapping(struct inst *copper, struct inst *other) static int refine_overlapping(struct inst *copper, struct inst *other)
{ {
if (other->u.pad.layers & LAYER_PASTE) { if (other->u.pad.layers & LAYER_PASTE_TOP) {
copper->u.pad.layers &= ~LAYER_PASTE; copper->u.pad.layers &= ~LAYER_PASTE_TOP;
if (!inside(other, copper)) { if (!inside(other, copper)) {
fail("solder paste without copper underneath " fail("solder paste without copper underneath "
"(\"%s\" line %d, \"%s\" line %d)", "(\"%s\" line %d, \"%s\" line %d)",
@ -94,8 +107,8 @@ static int refine_overlapping(struct inst *copper, struct inst *other)
return 0; return 0;
} }
} }
if (other->u.pad.layers & LAYER_MASK) if (other->u.pad.layers & LAYER_MASK_TOP)
copper->u.pad.layers &= ~LAYER_MASK; copper->u.pad.layers &= ~LAYER_MASK_TOP;
return 1; 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) int refine_layers(void)
{ {
const struct pkg *pkg; const struct pkg *pkg;
@ -138,8 +162,11 @@ int refine_layers(void)
for (pkg = pkgs; pkg; pkg = pkg->next) for (pkg = pkgs; pkg; pkg = pkg->next)
for (copper = pkg->insts[ip_pad_copper]; copper; for (copper = pkg->insts[ip_pad_copper]; copper;
copper = copper->next) copper = copper->next) {
if (!refine_copper(pkg, copper)) if (!refine_copper(pkg, copper))
return 0; return 0;
if (copper->u.pad.hole)
mirror_layers(&copper->u.pad.layers);
}
return 1; return 1;
} }

View File

@ -1,8 +1,8 @@
/* /*
* layer.h - PCB layers on a pad * layer.h - PCB layers on a pad
* *
* 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
@ -73,6 +73,8 @@ enum pad_type {
layer_type pad_type_to_layers(enum pad_type type); layer_type pad_type_to_layers(enum pad_type type);
enum pad_type layers_to_pad_type(layer_type layers); enum pad_type layers_to_pad_type(layer_type layers);
layer_type mech_hole_layers(void);
int refine_layers(void); int refine_layers(void);
#endif /* !LAYER_H */ #endif /* !LAYER_H */