#! /usr/bin/perl use strict; use warnings; if( @ARGV < 3 ) { print( STDERR "usage: $0 \n" ); exit( -1 ); } my $pins = int( $ARGV[0] ); my $pin_spacing = $ARGV[1]; my $side_len = $ARGV[2]; my $pin_dist = $pin_spacing; my $pin_width = $pin_spacing * 0.5; my $pin_begin = 0.5; my $pin_len = 1.5; my $silk_dist = 0.3; my $pcb_clearance = 3000; my $pcb_solder_add = 400; my $pcb_silk_width = 700; my $pins_side = int( $pins / 4 ); if( $pins_side * 4 != $pins ) { print( STDERR "number of pins not divisble by 4\n" ); exit( -1 ); } sub mm2pcb { my $mm = shift; my $pcb = $mm / 0.000254; my $pcb_i = $pcb < 0 ? int( $pcb - 0.5 ) : int( $pcb + 0.5 ); return $pcb_i; } sub pad { my ($x1, $y1, $x2, $y2, $no) = @_; my $dx = abs( $x2 - $x1 ); my $dy = abs( $y2 - $y1 ); my $width = $dx < $dy ? $dx : $dy; my $width2 = $width / 2; my $cx = ($x1 + $x2) / 2; my $cy = ($y1 + $y2) / 2; my $dx1 = $x1 - $cx; my $dx2 = $x2 - $cx; my $dy1 = $y1 - $cy; my $dy2 = $y2 - $cy; $x1 += $dx1 < 0 ? $width2 : -$width2; $x2 += $dx2 < 0 ? $width2 : -$width2; $y1 += $dy1 < 0 ? $width2 : -$width2; $y2 += $dy2 < 0 ? $width2 : -$width2; my $pcb_width = mm2pcb( $width ); printf( "\tPad[%d %d %d %d %d %d %d \"%d\" \"%d\" \"square\"]\n", mm2pcb( $x1 ), mm2pcb( $y1 ), mm2pcb( $x2 ), mm2pcb( $y2 ), $pcb_width, $pcb_clearance, $pcb_width + $pcb_solder_add, $no, $no ); } sub line { my ($x1, $y1, $x2, $y2) = @_; printf( "\tElementLine[%d %d %d %d %d]\n", mm2pcb( $x1 ), mm2pcb( $y1 ), mm2pcb( $x2 ), mm2pcb( $y2 ), $pcb_silk_width ); } my $d_side = $side_len / 2; my $d_pins_inner = $d_side + $pin_begin; my $d_pins_outer = $d_pins_inner + $pin_len; my $d_corner = $d_side + $silk_dist; my $d_corner_pins = ($pins_side + 1) / 2 * $pin_dist; my $d_outline = $d_pins_outer + $silk_dist; my $name_pitch = sprintf( "%f", $pin_spacing ); $name_pitch =~ s/[^0-9]//g; $name_pitch =~ s/0*$//g; my $name = "QFP" . sprintf( "%d", $pins ) . "_" . $name_pitch; printf( "Element[\"\" \"%s\" \"IC1\" \"%s\" 0 0 %d %d 0 100 \"\"]\n(\n", $name, $name, mm2pcb( -$d_outline ), mm2pcb( $d_outline ) + 1000 ); for( my $i = 0; $i < $pins_side; $i++ ) { my $d = ($i - ($pins_side - 1) / 2) * $pin_dist; my $d1 = $d - $pin_width / 2; my $d2 = $d + $pin_width / 2; pad( -$d_pins_outer, $d1, -$d_pins_inner, $d2, $i + 1 ); pad( $d1, $d_pins_outer, $d2, $d_pins_inner, $i + $pins_side + 1 ); pad( $d_pins_outer, -$d1, $d_pins_inner, -$d2, $i + 2 * $pins_side + 1 ); pad( -$d1, -$d_pins_outer, -$d2, -$d_pins_inner, $i + 3 * $pins_side + 1 ); } line( -$d_corner_pins, -$d_corner, $d_corner, -$d_corner ); line( $d_corner, -$d_corner, $d_corner, $d_corner ); line( $d_corner, $d_corner, -$d_corner, $d_corner ); line( -$d_corner, $d_corner, -$d_corner, -$d_corner_pins ); line( -$d_corner_pins, -$d_corner, -$d_corner, -$d_corner_pins ); line( -$d_corner, -$d_outline, $d_outline, -$d_outline ); line( $d_outline, -$d_outline, $d_outline, $d_outline ); line( $d_outline, $d_outline, -$d_outline, $d_outline ); line( -$d_outline, $d_outline, -$d_outline, -$d_corner ); line( -$d_corner, -$d_outline, -$d_outline, -$d_corner ); print( "\t)\n" );