r5941 - trunk/eda/fped

werner at docs.openmoko.org werner at docs.openmoko.org
Sun Apr 25 17:27:27 CEST 2010


Author: werner
Date: 2010-04-25 17:27:27 +0200 (Sun, 25 Apr 2010)
New Revision: 5941

Modified:
   trunk/eda/fped/gui_style.c
   trunk/eda/fped/inst.c
   trunk/eda/fped/inst.h
   trunk/eda/fped/kicad.c
   trunk/eda/fped/layer.c
   trunk/eda/fped/layer.h
Log:
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



Modified: trunk/eda/fped/gui_style.c
===================================================================
--- trunk/eda/fped/gui_style.c	2010-04-25 13:09:36 UTC (rev 5940)
+++ trunk/eda/fped/gui_style.c	2010-04-25 15:27:27 UTC (rev 5941)
@@ -71,7 +71,7 @@
 	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);
 

Modified: trunk/eda/fped/inst.c
===================================================================
--- trunk/eda/fped/inst.c	2010-04-25 13:09:36 UTC (rev 5940)
+++ trunk/eda/fped/inst.c	2010-04-25 15:27:27 UTC (rev 5941)
@@ -933,6 +933,7 @@
 	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);

Modified: trunk/eda/fped/inst.h
===================================================================
--- trunk/eda/fped/inst.h	2010-04-25 13:09:36 UTC (rev 5940)
+++ trunk/eda/fped/inst.h	2010-04-25 15:27:27 UTC (rev 5941)
@@ -102,6 +102,7 @@
 		} pad;
 		struct {
 			struct coord other;
+			layer_type layers; /* bit-set of layers (mech only) */
 			struct inst *pad; /* through-hole pad of NULL */
 		} hole;
 		struct {

Modified: trunk/eda/fped/kicad.c
===================================================================
--- trunk/eda/fped/kicad.c	2010-04-25 13:09:36 UTC (rev 5940)
+++ trunk/eda/fped/kicad.c	2010-04-25 15:27:27 UTC (rev 5941)
@@ -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 @@
 		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 @@
  	 */
 	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 @@
 	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;

Modified: trunk/eda/fped/layer.c
===================================================================
--- trunk/eda/fped/layer.c	2010-04-25 13:09:36 UTC (rev 5940)
+++ trunk/eda/fped/layer.c	2010-04-25 15:27:27 UTC (rev 5941)
@@ -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 @@
 
 	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 @@
 
 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 @@
 			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 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 @@
 
 	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;
 }

Modified: trunk/eda/fped/layer.h
===================================================================
--- trunk/eda/fped/layer.h	2010-04-25 13:09:36 UTC (rev 5940)
+++ trunk/eda/fped/layer.h	2010-04-25 15:27:27 UTC (rev 5941)
@@ -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 @@
 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 */




More information about the commitlog mailing list