diff pads2gpcb/decals.c @ 41:a2d304ec3817

pads2gpcb: decal processing code compiles
author Mychaela Falconia <falcon@ivan.Harhan.ORG>
date Mon, 11 Jan 2016 18:31:44 +0000
parents 1c37bec20596
children 4a50888d09ce
line wrap: on
line diff
--- a/pads2gpcb/decals.c	Mon Jan 11 08:12:40 2016 +0000
+++ b/pads2gpcb/decals.c	Mon Jan 11 18:31:44 2016 +0000
@@ -11,8 +11,9 @@
 static struct part_decal *current_decal;
 static struct footprint_body fpbody;
 static struct footprint_pad *pins_array;
-static int num_drawing_pieces, num_padstack_defs;
-static int num_text_items, num_attr_labels;
+
+#define	SOLDERMASK_DELTA	(600 * 254)
+#define	CLEARANCE_SETTING	(2000 * 254)
 
 static void
 enter_decal()
@@ -36,7 +37,7 @@
 	strcpy(p->name, name);
 	p->body = 0;
 	p->next = 0;
-	**pp = p;
+	*pp = p;
 	current_decal = p;
 }
 
@@ -104,27 +105,160 @@
 	}
 	input_line_fields[0]++;
 
-	if (atoi(input_line_fields[4]) != i + 1) {
+	if (atoi(input_line_fields[4]) != idx + 1) {
 		fprintf(stderr,
 			"%s line %d: expected %d in the pin number field\n",
 			input_filename, input_lineno);
 		exit(1);
 	}
-	pins_array[i].x1 = convert_input_dim(input_line_fields[0]);
-	pins_array[i].y1 = -convert_input_dim(input_line_fields[1]);
+	pins_array[idx].x1 = convert_input_dim(input_line_fields[0]);
+	pins_array[idx].y1 = -convert_input_dim(input_line_fields[1]);
+}
+
+static void
+process_pad_shape(padptr)
+	struct pad_shape_info *padptr;
+{
+	padptr->short_dim = convert_input_dim(input_line_fields[1]);
+	if (padptr->short_dim <= 0) {
+		printf("line %d: pad short dim <= 0\n", input_lineno);
+		return;
+	}
+	if (!strcmp(input_line_fields[2], "R")) {
+		padptr->rounded = 1;
+		padptr->elongated = 0;
+	} else if (!strcmp(input_line_fields[2], "S")) {
+		padptr->rounded = 0;
+		padptr->elongated = 0;
+	} else if (!strcmp(input_line_fields[2], "OF")) {
+		padptr->rounded = 1;
+		padptr->elongated = 1;
+	} else if (!strcmp(input_line_fields[2], "RF")) {
+		padptr->rounded = 0;
+		padptr->elongated = 1;
+	} else {
+		printf("line %d: unsupported pad shape %s\n", input_lineno,
+			input_line_fields[2]);
+		return;
+	}
+	if (padptr->elongated) {
+		if (input_line_nfields < 6) {
+			fprintf(stderr,
+			"%s line %d: too few fields in OF/RF pad stack line\n",
+				input_filename, input_lineno);
+			exit(1);
+		}
+		padptr->angle = parse_input_angle_90s(input_line_fields[3]);
+		if (padptr->angle != 0 && padptr->angle != 90) {
+			printf("line %d: unsupported OF/RF angle\n",
+				input_lineno);
+			return;
+		}
+		padptr->long_dim = convert_input_dim(input_line_fields[4]);
+		if (strcmp(input_line_fields[5], "0")) {
+			printf("line %d: unsupported nonzero finoffset\n",
+				input_lineno);
+			return;
+		}
+		if (padptr->long_dim <= padptr->short_dim) {
+			printf("line %d: OF/RF long dim <= short dim\n",
+				input_lineno);
+			return;
+		}
+	}
+	padptr->valid = 1;
 }
 
 static void
 one_padstack_def()
 {
+	int pinno, stacklines, i;
+	struct pad_shape_info *padptr;
 
+	get_line_internal();
+	parse_input_line_fields();
+	if (input_line_nfields != 3 || strcmp(input_line_fields[0], "PAD")) {
+		fprintf(stderr, "%s line %d: expected PAD header line\n",
+			input_filename, input_lineno);
+		exit(1);
+	}
+	pinno = atoi(input_line_fields[1]);
+	stacklines = atoi(input_line_fields[2]);
 
+	if (pinno < 0 || pinno > fpbody.npins) {
+		fprintf(stderr, "%s line %d: PAD pinno field invalid\n",
+			input_filename, input_lineno);
+		exit(1);
+	}
+	if (pinno)
+		padptr = &pins_array[pinno-1].shape;
+	else
+		padptr = &fpbody.default_pad;
+
+	for (i = 0; i < stacklines; i++) {
+		get_line_internal();
+		parse_input_line_fields();
+		if (input_line_nfields < 3) {
+			fprintf(stderr,
+			"%s line %d: too few fields in pad stack line\n",
+				input_filename, input_lineno);
+			exit(1);
+		}
+		if (!strcmp(input_line_fields[0], "-2"))
+			process_pad_shape(padptr);
+	}
+}
+
+static void
+apply_default_padstack()
+{
+	int i;
+
+	if (!fpbody.default_pad.valid)
+		return;
+	for (i = 0; i < fpbody.npins; i++)
+		if (!pins_array[i].shape.valid)
+			pins_array[i].shape = fpbody.default_pad;
+}
+
+static
+convert_pad_to_gpcb(pinidx)
+{
+	struct footprint_pad *pin = pins_array + pinidx;
+	long long_minus_short;
+
+	if (!pin->shape.valid) {
+		printf("error: no pad shape for pin #%d\n", pinidx + 1);
+		return(-1);
+	}
+	pin->thickness = pin->shape.short_dim;
+	pin->clearance = CLEARANCE_SETTING;
+	pin->mask = pin->thickness + SOLDERMASK_DELTA;
+	if (!pin->shape.elongated) {
+		pin->x2 = pin->x1;
+		pin->y2 = pin->y1;
+		return(0);
+	}
+	long_minus_short = pin->shape.long_dim - pin->shape.short_dim;
+	switch (pin->shape.angle) {
+	case 0:
+		pin->x2 = pin->x1 + long_minus_short;
+		pin->y2 = pin->y1;
+		return(0);
+	case 90:
+		pin->x2 = pin->x1;
+		pin->y2 = pin->y1 - long_minus_short;
+		return(0);
+	}
+	return(-1);
 }
 
 static void
 process_one_decal()
 {
-	int i;
+	int num_drawing_pieces, num_padstack_defs;
+	int num_text_items, num_attr_labels;
+	int i, valid;
 
 	if (input_line_nfields < 7 || input_line_nfields > 9) {
 		fprintf(stderr,
@@ -133,6 +267,7 @@
 		exit(1);
 	}
 	enter_decal();
+	printf("Processing decal %s\n", current_decal->name);
 	bzero(&fpbody, sizeof fpbody);
 	if (input_line_fields[1][0] != 'I' && input_line_fields[1][0] != 'M'
 	    || input_line_fields[1][1]) {
@@ -196,7 +331,25 @@
 	for (i = 0; i < num_padstack_defs; i++)
 		one_padstack_def();
 
-
+	/* post-processing */
+	apply_default_padstack();
+	valid = 1;
+	for (i = 0; i < fpbody.npins; i++)
+		if (convert_pad_to_gpcb(i) < 0)
+			valid = 0;
+	if (valid) {
+		/* good, save it */
+		current_decal->body = malloc(sizeof(struct footprint_body));
+		if (!current_decal->body) {
+			perror("malloc to save footprint body");
+			exit(1);
+		}
+		*current_decal->body = fpbody;
+		/* optional file output will go here */
+	} else {
+		printf("decal to gpcb fp conversion FAILED\n");
+		free(pins_array);
+	}
 }
 
 process_partdecal_section()