Index: parametric_lht/common.awk =================================================================== --- parametric_lht/common.awk (revision 27186) +++ parametric_lht/common.awk (revision 27187) @@ -170,6 +170,27 @@ LAYER[layer] = LAYER[layer] NL s } +function subc_rect(layer, x1, y1, x2, y2, clearance, flags, attributes ,s) +{ + w = w/2 + h = h/2 + s = s " ha:polygon." ++objid " {" NL + s = s " clearance=" unit(clearance) NL + s = s " li:geometry {" NL + s = s " ta:contour {" NL + s = s " { " unit(x1) "; " unit(y1) " }" NL + s = s " { " unit(x2) "; " unit(y1) " }" NL + s = s " { " unit(x2) "; " unit(y2) " }" NL + s = s " { " unit(x1) "; " unit(y2) " }" NL + s = s " }" NL + s = s " }" NL + s = s " ha:attributes {" attributes "}" NL + s = s " ha:flags {" flags "}" NL + s = s " }" NL + + LAYER[layer] = LAYER[layer] NL s +} + # start generating a subcircuit function subc_begin(footprint, refdes, refdes_x, refdes_y, refdes_dir) { @@ -312,6 +333,19 @@ PROTO[proto] = PROTO[proto] s } +function subc_pstk_add_shape_line(proto, layer, x1, y1, x2, y2, thick ,s) +{ + s = s " ha:ps_shape_v4 {" NL + s = s " clearance = 0" NL + s = s " ha:ps_line {" NL + s = s " x1=" unit(x1) "; y1=" unit(y1) "; x2=" unit(x2) "; y2=" unit(y2) ";" NL + s = s " thickness=" unit(thick) "; square=0" NL + s = s " }" NL + s = s subc_pstk_shape_layer(layer) + s = s " }" NL + PROTO[proto] = PROTO[proto] s +} + function subc_proto_create_pin_round(drill_dia, ring_dia, mask_dia ,proto) { proto = subc_proto_alloc() @@ -378,6 +412,56 @@ return proto } +function subc_proto_create_pad_line(x1, x2, thick, mask, paste ,proto,m,p) +{ + proto = subc_proto_alloc() + + thick = either(thick, parse_dim(DEFAULT["pad_thickness"])) + + subc_pstk_no_hole(proto) + + PROTO_COMMENT[proto] = "# Square smd pad " x2-x1 " * " thick + PROTO[proto] = PROTO[proto] " li:shape {" NL + + subc_pstk_add_shape_line(proto, "top-copper", x1, 0, x2, 0, thick) + subc_pstk_add_shape_line(proto, "top-mask", x1, 0, x2, 0, either(mask, DEFAULT["pad_mask"])) + subc_pstk_add_shape_line(proto, "top-paste", x1, 0, x2, 0, either(paste, DEFAULT["pad_paste"])) + + PROTO[proto] = PROTO[proto] " }" NL + + return proto +} + +function subc_proto_create_pad_rect(w, h, mask_offs, paste_offs ,proto,m,p) +{ + proto = subc_proto_alloc() + + subc_pstk_no_hole(proto) + + PROTO_COMMENT[proto] = "# Square smd pad " w " * " h + PROTO[proto] = PROTO[proto] " li:shape {" NL + + w = w/2 + h = h/2 + + subc_pstk_add_shape_square_corners(proto, "top-copper", -w, -h, +w, +h) + + if (mask_offs != "none") { + m = (either(mask_offs, (DEFAULT["pad_mask"]) - DEFAULT["pad_thickness"]) / 2) + subc_pstk_add_shape_square_corners(proto, "top-mask", -w-m, -h-m, +w+m, +h+m) + } + + if (paste_offs != "none") { + p = (either(paste_offs, (DEFAULT["pad_paste"]) - DEFAULT["pad_thickness"]) / 2) + subc_pstk_add_shape_square_corners(proto, "top-paste", -w-p, -h-p, +w+p, +h+p) + } + + PROTO[proto] = PROTO[proto] " }" NL + + return proto +} + + function subc_proto_create_pad_circle(dia, mask_dia, paste_dia ,proto) { proto = subc_proto_alloc() @@ -468,15 +552,6 @@ } } -# draw a matrix of pads; top-left corner is x1;y1, there are nx*ny pads -# of w*h size. rows/cols of pads are drawn with ox and oy offset -function subc_pad_matrix(x1, y1, nx, ny, w, h, ox, oy, number, flags, clearance, mask, name, ix,iy) -{ - for(iy = 0; iy < ny; iy++) - for(ix = 0; ix < nx; ix++) - element_pad_rectangle(x1+ix*ox, y1+iy*oy, x1+ix*ox+w, y1+iy*oy+h, number, flags, clearance, mask, name) -} - # draw element pad circle function subc_pad_circle(x1, y1, radius, number, clearance, mask, name) { @@ -575,23 +650,23 @@ # draw a rectangle corners of silk lines, wx and wy long in x and y directions # omit sides as requested in omit: NW, NW, SW, SE # corners are always sharp -function element_rectangle_corners(x1, y1, x2, y2, wx, wy, omit, thickness ,tmp) +function subc_rectangle_corners(layer, x1, y1, x2, y2, wx, wy, omit, thickness ,tmp) { if (!(omit ~ "NW")) { - element_line(x1, y1, x1+wx, y1, thickness) - element_line(x1, y1, x1, y1+wy, thickness) + subc_line(layer, x1, y1, x1+wx, y1, thickness) + subc_line(layer, x1, y1, x1, y1+wy, thickness) } if (!(omit ~ "NE")) { - element_line(x2-wx, y1, x2, y1, thickness) - element_line(x2, y1, x2, y1+wy, thickness) + subc_line(layer, x2-wx, y1, x2, y1, thickness) + subc_line(layer, x2, y1, x2, y1+wy, thickness) } if (!(omit ~ "SW")) { - element_line(x1, y2, x1+wx, y2, thickness) - element_line(x1, y2-wy, x1, y2, thickness) + subc_line(layer, x1, y2, x1+wx, y2, thickness) + subc_line(layer, x1, y2-wy, x1, y2, thickness) } if (!(omit ~ "SE")) { - element_line(x2-wx, y2, x2, y2, thickness) - element_line(x2, y2-wy, x2, y2, thickness) + subc_line(layer, x2-wx, y2, x2, y2, thickness) + subc_line(layer, x2, y2-wy, x2, y2, thickness) } } Index: parametric_lht/plcc.awk =================================================================== --- parametric_lht/plcc.awk (nonexistent) +++ parametric_lht/plcc.awk (revision 27187) @@ -0,0 +1,60 @@ +function parri(A ,s,i) +{ + for(i in A) + s = s " " i + return s +} + +BEGIN { + base_unit_mm = 0 + + help_auto() + PT["50"] = "26mil" + set_arg(P, "?pitch", "50") + + proc_args(P, "pins,size,pitch,cpad_size,pad_thickness", "pins") + + pitch = P["pitch"] + sub("[.]0*$", "", pitch) + + if (!(args ~ "pad_thickness=")) { + if (!(pitch in PT)) + error("Unknown pitch (" pitch "), should be one of:" parri(PT)) + pt = PT[pitch] + } + else + pt = rev_mil(DEFAULT["pad_thickness"]) + + if (P["size"] == "") + P["size"] = int(P["pins"] * (pitch/4) + 140) + + split(P["size"], S, "x") + if (S[2] == "") + S[2] = S[1] + if (S[1] != S[2]) + error("need n*n size") + + pins = int(P["pins"]) + if (pins / 4 != int(pins / 4)) + error("number of pins must be divisible by 4") + + pins=pins/4 + + if ((pins % 2) != 1) + error("number of pins per side must be odd") + + S[1] -= 60 + S[2] -= 60 + args = args ",nx=" pins ",ny=" pins ",x_spacing=" S[1] "mil,y_spacing=" S[2] "mil,pad_spacing=" pitch "mil,pad_thickness=" pt "mil" + + args = args ",width=" S[1]-150 " mil,height=" S[2]-150 " mil" + + + if (P["cpad_size"] != "") + args = args ",cpad_width=" P["cpad_size"] "mil,cpad_height=" P["cpad_size"] "mil" + + args = args ",int_bloat=47mil,ext_bloat=47mil" + args = args ",?bodysilk=plcc,?silkmark=circle,pinoffs=" int(pins/2+0.5) + + +} Index: parametric_lht/plcc_lht =================================================================== --- parametric_lht/plcc_lht (nonexistent) +++ parametric_lht/plcc_lht (revision 27187) @@ -0,0 +1,29 @@ +#!/bin/sh + +# Reference: Microchip Packaging Specification DS00000049BX (en012702.pdf), SSOP + +#@@example plcc(20) + +#@@purpose Generate PLCC packages +#@@desc Generate square PLCC packages - a simplified frontend to qf() - +#@@desc only the number of pins is really needed for a square PLCC footprint! +#@@desc NOTE: some of the qf() parameters can be also used; PLCC32 is non-square, and can not be properly generated using this generator. + +#@@params pins,size,pitch,cpad_size + +#@@param:pins total number of pins (leads); must be divisible by 4 + +#@@param:size a single integer N or NxN or NxNxH; outmost dimensions (width or height of the package, leads included) in mil +#@@optional:size +#@@default:size calculated from total number of pins and pitch + +#@@param:pitch lead pitch (distance between the centerline of two adjacent leads), in mil; must be 50 for now +#@@optional:pitch +#@@default:pitch 50mil + +#@@param:cpad_size width (and height) of the central pad, in mil +#@@optional:cpad_size +#@@default:cpad_size empty, there's no central pad + +awk -f `dirname $0`/common.awk -f `dirname $0`/plcc.awk -f `dirname $0`/qf.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: parametric_lht/plcc_lht ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: parametric_lht/qf.awk =================================================================== --- parametric_lht/qf.awk (nonexistent) +++ parametric_lht/qf.awk (revision 27187) @@ -0,0 +1,193 @@ +function qf_globals(pre_args, post_args ,reqs) +{ + DEFAULT["cpad_mask", "dim"] = 1 + + if (hook_spc_conv == "") + hook_spc_conv = 1.8 + if (hook_cpad_mult == "") + hook_cpad_mult = 1 + + if (!qf_no_defaults) { + set_arg(P, "?pad_spacing", "0.5mm") + set_arg(P, "?ext_bloat", "0.37mm") + set_arg(P, "?int_bloat", "0.37mm") + set_arg(P, "?pad_thickness", "0.3mm") + set_arg(P, "?silkmark", "dot") + set_arg(P, "?line_thickness", "0.1mm") + set_arg(P, "?cpm_width", "1mm") + set_arg(P, "?cpm_height", "1mm") + set_arg(P, "?cpm_nx", "2") + set_arg(P, "?cpm_ny", "2") + } + + reqs = "nx,ny" + + if (pre_args != "") + reqs="" + + if ((post_args != "") && (!(post_args ~ "^,"))) + post_args = "," post_args + + if ((pre_args != "") && (!(pre_args ~ ",$"))) + pre_args = pre_args "," + + proc_args(P, pre_args "nx,ny,x_spacing,y_spacing,pad_spacing,ext_bloat,int_bloat,width,height,cpad_width,cpad_height,cpad_auto,cpm_nx,cpm_ny,cpm_width,cpm_height,cpad_mask,rpad_round,bodysilk,pinoffs,silkmark" post_args, reqs) + + nx = int(P["nx"]) + ny = int(P["ny"]) + + if (P["ny"] == "") + ny = nx + + if ((nx < 2) || (ny < 2)) + error("Number of pins have to be more than 2 in both directions") + + x_spacing=parse_dim(P["x_spacing"]) + y_spacing=parse_dim(P["y_spacing"]) + pad_spacing=parse_dim(P["pad_spacing"]) + pt = DEFAULT["pad_thickness"] + ext_bloat=parse_dim(P["ext_bloat"]) - pt/2 + int_bloat=parse_dim(P["int_bloat"]) - pt/2 + width=parse_dim(P["width"]) + height=parse_dim(P["height"]) + pinoffs = int(P["pinoffs"]) + + if (x_spacing == "") + x_spacing = (nx+hook_spc_conv) * pad_spacing + if (y_spacing == "") + y_spacing = (ny+hook_spc_conv) * pad_spacing + + cpad_width=parse_dim(P["cpad_width"]) + cpad_height=parse_dim(P["cpad_height"]) + + if (P["cpad_mask"] != "") + cpad_mask=parse_dim(P["cpad_mask"]) + + + if (tobool(P["cpad_auto"]) || hook_cpad_auto) { + if (cpad_width == "") + cpad_width = (x_spacing*0.85 - int_bloat*2 - pt) * hook_cpad_mult + if (cpad_height == "") + cpad_height = (y_spacing*0.85 - int_bloat*2 - pt) * hook_cpad_mult + } + + + if (width == "") + width = x_spacing + if (height == "") + height = y_spacing + + pinmax=(nx+ny)*2 + + if (!tobool(P["rpad_round"])) + rpad_round = "square" + else + rpad_round = "" + + + cpm_width = parse_dim(P["cpm_width"]) + cpm_height = parse_dim(P["cpm_height"]) + cpm_nx = int(P["cpm_nx"]) + cpm_ny = int(P["cpm_ny"]) +} + +function pinnum(num) +{ + return ((num-1) + pinoffs) % (pinmax)+1 +} + +# draw a matrix of paste rectangles; top-left corner is x1;y1, there are nx*ny +# rectangles of w*h size. rows/cols of pads are drawn with ox and oy offset +function paste_matrix(x1, y1, nx, ny, w, h, ox, oy, flags, attrbiutes, clearance, ix,iy) +{ + for(iy = 0; iy < ny; iy++) + for(ix = 0; ix < nx; ix++) + subc_rect("top-paste", x1+ix*ox, y1+iy*oy, x1+ix*ox+w, y1+iy*oy+h, clearance, flags, attributes) +} + + +BEGIN { + base_unit_mm = 0 + + help_auto() + qf_globals() + + subc_begin("", "U1", -width/2 - mm(1), -height/2 - mm(2), 0) + + cx = (nx+1)/2 + cy = (ny+1)/2 + + if (rpad_round) + proto = subc_proto_create_pad_line(-ext_bloat, int_bloat, pad_width) + else + proto = subc_proto_create_pad_sqline(-ext_bloat, int_bloat, pad_width) + + for(n = 1; n <= ny; n++) { + y = (-cy + n) * pad_spacing + x1 = -x_spacing/2 + x2 = x_spacing/2 + subc_pstk(proto, x1, y, 0, pinnum(n)) + subc_pstk(proto, x2, y, 180, pinnum(nx+2*ny-n+1)) + if (n == 1) + y1 = y + if (n == 2) + dimension(x1, y1, x1, y, (ext_bloat * -3), "pad_spacing") + } + + dimension(x1, y-pt/2, x1, y+pt/2, (ext_bloat * -3), "pad_thickness") + + for(n = 1; n <= nx; n++) { + x = (-cx + n) * pad_spacing + y1 = -y_spacing/2 + y2 = y_spacing/2 + subc_pstk(proto, x, y1, 90, pinnum(nx*2+ny*2-n+1)) + subc_pstk(proto, x, y2, 270, pinnum(n+ny)) + } + + + if ((cpad_width != "") && (cpad_height != "")) { + cpadid = 2*nx+2*ny+1 +# center pad paste matrix + if ((cpm_nx > 0) && (cpm_ny > 0)) { + ox = (cpad_width - (cpm_nx*cpm_width)) / (cpm_nx - 1) + oy = (cpad_height - (cpm_ny*cpm_height)) / (cpm_ny - 1) + paste_matrix(-cpad_width/2, -cpad_height/2, cpm_nx,cpm_ny, cpm_width,cpm_height, + ox+cpm_width,oy+cpm_height, "", "termid=" cpadid ";", 0) + } + +# center pad + cpad_proto = subc_proto_create_pad_rect(cpad_width, cpad_height, cpad_mask, "none") + subc_pstk(cpad_proto, 0, 0, 0, cpadid) + dimension(-cpad_width/2, -cpad_height/2, +cpad_width/2, -cpad_height/2, "@0;" (height * -0.6-ext_bloat), "cpad_width") + dimension(cpad_width/2, -cpad_height/2, cpad_width/2, +cpad_height/2, "@" (width * 0.8+ext_bloat) ";0", "cpad_height") + } + + wx = (width - nx * pad_spacing) / 3.5 + wy = (height - ny * pad_spacing) / 3.5 + + bodysilk = P["bodysilk"] + if ((bodysilk == "corners") || (bodysilk == "")) { + subc_rectange_corners("top-silk", -width/2, -height/2, width/2, height/2, wx, wy) + silkmark(P["silkmark"], -width/2 - wx/2, -height/2+wy*1.5, (wx+wy)/4) + } + else if (bodysilk == "full") { + subc_rectange("top-silk", -width/2, -height/2, width/2, height/2) + silkmark(P["silkmark"], -width/2 + wx*3, -height/2+wy*3, (wx+wy)/2) + } + else if (bodysilk == "plcc") { + r = (width+height)/10 + subc_rectangle("top-silk", -width/2, -height/2, width/2, height/2, "arc,NE,SW,SE", r) + subc_line("top-silk", -width/2, -height/2+r, width/2, -height/2+r) + silkmark(P["silkmark"], 0, -height*0.2, height/40) + } + else if (bodysilk != "none") + error("invalid bodysilk parameter") + + dimension(-width/2, -height/2, +width/2, -height/2, "@0;" height*-0.8-ext_bloat, "width") + dimension(+width/2, -height/2, +width/2, +height/2, "@" (width * 1+ext_bloat) ";0", "height") + + dimension(-x_spacing/2, -height/2, +x_spacing/2, -height/2, "@0;" height*-1-ext_bloat, "x_spacing") + dimension(+width/2, -y_spacing/2, +width/2, +y_spacing/2, "@" (width * 1.2+ext_bloat) ";0", "y_spacing") + + subc_end() +}