Commit 1bf6c604 authored by Jan Kasprzak's avatar Jan Kasprzak
Browse files

Makefile: panelized design for 5x5cm fab

parent 6d789ebc
Loading
Loading
Loading
Loading
+16 −16
Original line number Diff line number Diff line
@@ -2,13 +2,13 @@ WEB_DIR=/home/kas/html/tinyboard/
WEB_FILES=pcb-back.png pcb-front.png schematics.png schematics-power.png \
	schematics-pin.png
GERBER_FILES=\
	tinyboard.top.gbr \
	tinyboard.bottom.gbr \
	tinyboard.topmask.gbr \
	tinyboard.bottommask.gbr \
	tinyboard.topsilk.gbr \
	tinyboard.bottomsilk.gbr \
	tinyboard.plated-drill.cnc
	tinyboard-panel.top.gbr \
	tinyboard-panel.bottom.gbr \
	tinyboard-panel.topmask.gbr \
	tinyboard-panel.bottommask.gbr \
	tinyboard-panel.topsilk.gbr \
	tinyboard-panel.bottomsilk.gbr \
	tinyboard-panel.plated-drill.cnc

all:
	@echo "Usage: make [clean|web|gerber|fab|tinyboard.pcb]"
@@ -43,18 +43,18 @@ schematics-pin.png: schematics.png

gerber: $(GERBER_FILES)

$(GERBER_FILES): tinyboard.pcb
	pcb -x gerber tinyboard.pcb
$(GERBER_FILES): tinyboard-panel.pcb
	pcb -x gerber tinyboard-panel.pcb

fab: $(GERBER_FILES)
	@sh -c 'D=tinyboard-`date +\%Y\%m\%d-\%H\%M` && mkdir $$D && \
		cp tinyboard.top.gbr $$D/tinyboard.gtl && \
		cp tinyboard.bottom.gbr $$D/tinyboard.gbl && \
		cp tinyboard.topmask.gbr $$D/tinyboard.gts && \
		cp tinyboard.bottommask.gbr $$D/tinyboard.gbs && \
		cp tinyboard.topsilk.gbr $$D/tinyboard.gto && \
		cp tinyboard.bottomsilk.gbr $$D/tinyboard.gbo && \
		cp tinyboard.plated-drill.cnc $$D/tinyboard.txt && \
		cp tinyboard-panel.top.gbr $$D/tinyboard.gtl && \
		cp tinyboard-panel.bottom.gbr $$D/tinyboard.gbl && \
		cp tinyboard-panel.topmask.gbr $$D/tinyboard.gts && \
		cp tinyboard-panel.bottommask.gbr $$D/tinyboard.gbs && \
		cp tinyboard-panel.topsilk.gbr $$D/tinyboard.gto && \
		cp tinyboard-panel.bottomsilk.gbr $$D/tinyboard.gbo && \
		cp tinyboard-panel.plated-drill.cnc $$D/tinyboard.txt && \
		zip -r $$D.zip $$D && \
		echo "Done. Output in $$D.zip."; \
		echo "You may also want to do git tag gerber-fab-$$D" '

panel.pl

0 → 100644
+126 −0
Original line number Diff line number Diff line
#!/usr/bin/perl
# -*- perl -*-

# Copyright 2006 DJ Delorie <dj@delorie.com>
# Released under the terms of the GNU General Public License, version 2

sub baseboard {
    my ($file, $width, $height, $nbase) = @_;
    if (! $nbase) {
	$base = $file;
	$base =~ s@.*/@@;
    } else {
	$base = $nbase;
    }

    $panelcopperlayers = ".*" unless $panelcopperlayers;

    $pscript = "$base.pscript";
    open(PS, ">$pscript");
    push(@files_to_remove, "$base.pscript");

    open(S, $file) || die("$file: $!");
    $outname = "$base.panel.pcb";
    $outname =~ s/pnl\.panel\.pcb/pcb/;
    open(O, ">$outname");
    while (<S>) {
	if (/PCB\[.* (\S+) (\S+)\]/) {
	    s/ (\S+) (\S+)\]/ $width $height\]/;
	}
	s/Cursor\[.*\]/Cursor[0 0 0.0]/;
	if (/^Flags/) {
	    s/,uniquename,/,/;
	    s/,uniquename//;
	    s/uniquename,//;
	}
	next if /\b(Via|Pin|Pad|ElementLine|Line|Arc|ElementArc|Text)/;
	if (/Polygon|Element/) {
	    $hole = 0;
	    while (<S>) {
		$hole++ if /Hole \(/;
		last if /^\s*\)\s*$/ && $hole <= 0;
		$hole-- if /\)/;
	    }
	    next;
	}
	if (/Layer/) {
	    if (@panelvias) {
		print O @panelvias;
		@panelvias = ();
	    }
	}
	print O;
	if (/Layer\((\d+) \"(.*)\"\)/) {
	    $lnum = $1;
	    $lname = $2;
	    print O scalar <S>;
	    print STDERR "layer $lnum $lname vs '$panelcopperlayers'\n";
	    if ($lnum =~ /$panelcopperlayers/ || $lname =~ /$panelcopperlayers/) {
		print O @panelcopper;
	    }
	}
    }
    close O;
    close S;

    print PS "LoadFrom(Layout,$outname)\n";

    $ox = $oy = 0;
}

sub loadboard {
    my ($file) = @_;
    $seq = 1 + $seq;

    open(S, $file);
    open(O, ">temp-panel.$seq");
    while (<S>) {
	if (/PCB\[.* (\S+) (\S+)\]/) {
	    $width = &parseval($1);
	    $height = &parseval($2);
	}
	s/Cursor\[.*\]/Cursor[0 0 0.0]/;
	print O;
    }
    close O;
    close S;
    print PS "LoadFrom(LayoutToBuffer,temp-panel.$seq)\n";
    push(@files_to_remove, "temp-panel.$seq");
}

sub opaste {
    $vx = $ox;
    $vy = $oy + $height;
    print PS "PasteBuffer(ToLayout,$ox,$oy)\n";
    $ox += $width;
    $oy = 0;
}

sub vpaste {
    print PS "PasteBuffer(ToLayout,$vx,$vy)\n";
    $vy += $height;
}

sub done {
    print PS "SaveTo(LayoutAs,$outname)\n";
    print PS "Quit()\n";

    close PS;

    system "set -x; pcb --action-script $pscript";
    #system "pcb -x ps $base.panel.pcb";
    #unlink @files_to_remove;
}

sub parseval {
    my ($v) = @_;
    if ($v =~ /mil/) {
	$v *= 100;
    }
    if ($v =~ /mm/) {
	$v *= 3937.007874015748;
    }
    return 0 + $v;
}

1;

panel2pcb

0 → 100755
+99 −0
Original line number Diff line number Diff line
#!/usr/bin/perl
# -*- perl -*-

# Copyright 2006 DJ Delorie <dj@delorie.com>
# Released under the terms of the GNU General Public License, version 2

if (! @ARGV) {
    print "Usage: pcb2panel board1.pcb board2.pcb board3.pcb > boards.pcb";
    print "Then edit boards.pcb, putting each outline where you want it\n";
    print "and sizing the board.  Then:\n";
    print "panel2pcb [-l regex] boards.pcb\n";
    print "and edit/print boards.panel.pcb\n";
    exit 0;
}

$mydir = $0;
if ($mydir =~ m@/@) {
    $mydir =~ s@[^/]*$@@;
} else {
    $mydir = ".";
}

require "$mydir/panel.pl";

$panel = shift;

if ($panel eq "-l") {
    $panelcopperlayers = shift;
    $panel = shift;
}

open(P, $panel);
while (<P>) {
    if (/PCB\[.* (\S+) (\S+)\]/) {
	$panel_width = &parseval($1);
	$panel_height = &parseval($2);
    }
    if (/Element\[\"[^\"]*\" \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" (\S+) (\S+)/) {
	$pcb = $1;
	$base = $2;
	$value = $3;
	$mx = &parseval($4);
	$my = &parseval($5);
	%pinx = ();
	%piny = ();
    }
    if (/Pin\[(\S+) (\S+) \S+ \S+ \S+ \S+ \"(\d)\"/) {
	$pinx{$3} = &parseval($1);
	$piny{$3} = &parseval($2);
    }
    if ($pcb && /\)/) {
	if ($pinx{'1'} < $pinx{'2'}) {
	    $rot = 0;
	} elsif ($pinx{'1'} > $pinx{'2'}) {
	    $rot = 2;
	} elsif ($piny{'1'} < $piny{'2'}) {
	    $rot = 3;
	} elsif ($piny{'1'} > $piny{'2'}) {
	    $rot = 1;
	}
	push (@paste, "$pcb\0$rot\0$mx\0$my");
	$pcb = undef;
    }
    if (/Via/) {
	push (@panelvias, $_);
    }
    if (/^Layer\([^)]*\)$/) {
	$junk = <P>; # The opening '('
	while ($junk = <P>) {
	    last if $junk =~ /^\)/;
	    push (@panelcopper, $junk);
	}
    }
}

$tmp = "/tmp/panel$$.pcb";

$start = $paste[0];
$start =~ s/\0.*//;

$panel =~ s/\.pcb$//;
&baseboard($start, $panel_width, $panel_height, $panel);

$lastboard = undef;
for $paste (sort @paste) {
    ($pcb, $rot, $mx, $my) = split(/\0/, $paste);
    if ($lastboard ne $pcb) {
	&loadboard ($pcb);
	$lastboard = $pcb;
	$lastrot = 0;
    }
    while ($lastrot != $rot) {
	print PS "PasteBuffer(Rotate,1)\n";
	$lastrot = ($lastrot+1) % 4;
    }
    print PS "PasteBuffer(ToLayout,$mx,$my)\n";
}

&done();

pcb2panel

0 → 100755
+101 −0
Original line number Diff line number Diff line
#!/usr/bin/perl
# -*- perl -*-

# Copyright 2006 DJ Delorie <dj@delorie.com>
# Released under the terms of the GNU General Public License, version 2

$mydir = $0;
if ($mydir =~ m@/@) {
    $mydir =~ s@[^/]*$@@;
} else {
    $mydir = ".";
}

require "$mydir/panel.pl";

if (! @ARGV) {
    print "Usage: pcb2panel board1.pcb board2.pcb board3.pcb > boards.pcb\n";
    print "Then edit boards.pcb, putting each outline where you want it\n";
    print "and sizing the board.  Then:\n";
    print "panel2pcb boards.pcb\n";
    print "and edit/print boards.panel.pcb\n";
    exit 0;
}

for $pcb (@ARGV) {
    $base = $pcb;
    $base =~ s@.*/@@;
    $base =~ s@\.pcb$@@;
    $base{$pcb} = $base;
    push (@pcbs, $pcb);
    open(PCB, $pcb);
    while (<PCB>) {
	if (/^PCB\[".*" (\S+) (\S+)\]/) {
	    $width{$pcb} = &parseval($1);
	    $height{$pcb} = &parseval($2);
	    printf STDERR "%s : %d x %d\n", $pcb, $width{$pcb}, $height{$pcb};
	    last;
	}
    }
    $outline = '';
    while (<PCB>) {
	if (/Layer\(.*"outline"\)/) {
	    $junk = <PCB>; # open paren
	    while (<PCB>) {
		last if /^\)/; # close paren
		($args) = m@\[(.*)\]@;
		($x1, $y1, $x2, $y2, $width) = split(' ', $args);
		$outline .= "  ElementLine[$x1 $y1 $x2 $y2 $width]\n";
	    }
	}
    }
    push (@outlines, $outline);
    close PCB;
}

$pw = 10000;
$ph = 0;
for $pcb (@pcbs) {
    $pw += 10000;
    $pw += $width{$pcb};
    $ph = $height{$pcb} if $ph < $height{$pcb};
}
$ph += 20000;

print "PCB[\"\" $pw $ph]\n";
print "Grid[10000.0 0 0 1]\n";
print "DRC[799 799 800 100 1500 800]\n";
print "Groups(\"1,c:2,s\")\n"; #"

$x = 10000;
$y = 10000;
for ($i=0; $i<@pcbs; $i++) {
    $pcb = $pcbs[$i];
    $outline = $outlines[$i];
    $desc = $pcb;
    $name = $base{$pcb};
    $value = "$width{$pcb} x $height{$pcb}";
    $w = $width{$pcb};
    $h = $height{$pcb};

    print "Element[\"\" \"$desc\" \"$name\" \"$value\" $x $y 2000 2000 0 50 \"\"] (\n";
    print "  Pin[0  0 1000 0 0 400 \"1\" \"1\" \"\"]\n";
    print "  Pin[$w 0 1000 0 0 400 \"2\" \"2\" \"\"]\n";
    if ($outline =~ /\S/) {
	print $outline;
    } else {
	print "  ElementLine[0 0 $w 0 100]\n";
	print "  ElementLine[0 0 0 $h 100]\n";
	print "  ElementLine[$w 0 $w $h 100]\n";
	print "  ElementLine[0 $h $w $h 100]\n";
    }
    print ")\n";
    $x += $w + 10000;
}

print "Layer(1 \"component\")()\n";
print "Layer(2 \"solder\")()\n";
print "Layer(3 \"silk\")()\n";
print "Layer(4 \"silk\")()\n";

exit 0;