00001
00025 #include "register_functions.c"
00026 #include "plcc.h"
00027
00028
00035 int
00036 plcc_create_element ()
00037 {
00038 gdouble xmax;
00039 gdouble xmin;
00040 gdouble ymax;
00041 gdouble ymin;
00042 gdouble x_text;
00043 gdouble y_text;
00044 gdouble x0;
00045 gdouble x1;
00046 gdouble y0;
00047 gdouble y1;
00048 gdouble y_dot;
00049 gdouble dx;
00050 gint i;
00051 gint pin_number;
00052 gchar *pin_pad_name = g_strdup ("");
00053 FlagType pad_flag;
00054 ElementTypePtr element;
00055
00056 if (!element)
00057 {
00058 if (verbose)
00059 g_log ("", G_LOG_LEVEL_WARNING,
00060 _("could not create a valid element pointer for a %s package."),
00061 footprint_type);
00062 return (EXIT_FAILURE);
00063 }
00064
00065
00066 element->MarkX = 0;
00067 element->MarkY = 0;
00068
00069
00070
00071
00072
00073 if ((multiplier * ((-package_body_length / 2.0) - courtyard_clearance_with_package)) < xmin)
00074 {
00075 xmin = (multiplier * ((-package_body_length / 2.0) - courtyard_clearance_with_package));
00076 }
00077 if ((multiplier * ((package_body_length / 2.0) + courtyard_clearance_with_package)) > xmax)
00078 {
00079 xmax = (multiplier * ((package_body_length / 2.0) + courtyard_clearance_with_package));
00080 }
00081 if ((multiplier * ((-package_body_width / 2.0) - courtyard_clearance_with_package)) < ymin)
00082 {
00083 ymin = (multiplier * ((-package_body_width / 2.0) - courtyard_clearance_with_package));
00084 }
00085 if ((multiplier * ((package_body_width / 2.0) + courtyard_clearance_with_package)) > ymax)
00086 {
00087 ymax = (multiplier * ((package_body_width / 2.0) + courtyard_clearance_with_package));
00088 }
00089
00090 if (multiplier * (-courtyard_length / 2.0) < xmin)
00091 {
00092 xmin = multiplier * (-courtyard_length / 2.0);
00093 }
00094 if (multiplier * (courtyard_length / 2.0) > xmax)
00095 {
00096 xmax = multiplier * (courtyard_length / 2.0);
00097 }
00098 if (multiplier * (-courtyard_width / 2.0) < ymin)
00099 {
00100 ymin = multiplier * (-courtyard_width / 2.0);
00101 }
00102 if (multiplier * (courtyard_width / 2.0) > ymax)
00103 {
00104 ymax = multiplier * (courtyard_width / 2.0);
00105 }
00106
00107 element->Name[1].Scale = 100;
00108 element->Name[1].X = 0.0 ;
00109 element->Name[1].Y = (ymin - 10000.0);
00110 element->Name[1].TextString = footprint_name;
00111 element->Name[1].Element = element;
00112 element->Name[1].Direction = EAST;
00113 element->Name[1].ID = ID++;
00114
00115 element->Name[2].Scale = 100;
00116 element->Name[2].X = 0.0 ;
00117 element->Name[2].Y = (ymin - 10000.0);
00118 element->Name[2].TextString = footprint_refdes;
00119 element->Name[2].Element = element;
00120 element->Name[2].Direction = EAST;
00121 element->Name[2].ID = ID++;
00122
00123 element->Name[3].Scale = 100;
00124 element->Name[3].X = 0.0 ;
00125 element->Name[3].Y = (ymin - 10000.0);
00126 element->Name[3].TextString = footprint_value;
00127 element->Name[3].Element = element;
00128 element->Name[3].Direction = EAST;
00129 element->Name[3].ID = ID++;
00130
00131
00132
00133
00134 if (c1_state)
00135 {
00136 y0 = ((-c1 - pad_length + pad_width) / 2.0);
00137 y1 = ((-c1 + pad_length - pad_width) / 2.0);
00138 }
00139 if (g1_state)
00140 {
00141 y0 = ((-g1 + pad_width) / 2.0) - pad_length;
00142 y1 = ((-g1 - pad_width) / 2.0);
00143 }
00144 if (z1_state)
00145 {
00146 y0 = ((-z1 + pad_width) / 2.0);
00147 y1 = ((-z1 - pad_width) / 2.0) + pad_length;
00148 }
00149 for (pin_number = 1;
00150 pin_number < ((count_x / 2) + 1.5);
00151 pin_number++)
00152 {
00153 if (pin1_square && (pin_number == 1))
00154 {
00155 pad_flag.f = SQUARE;
00156 }
00157 else if (pad_shapes_type == SQUARE)
00158 {
00159 pad_flag.f = SQUARE;
00160 }
00161 else
00162 {
00163 pad_flag.f = CLEAR;
00164 }
00165 create_new_pad
00166 (
00167 element,
00168 (int) (multiplier * ((-pin_number + 1) * pitch_x)),
00169 (int) (multiplier * y0),
00170 (int) (multiplier * ((-pin_number + 1) * pitch_x)),
00171 (int) (multiplier * y1),
00172 (int) (multiplier * pad_width),
00173 (int) (multiplier * pad_clearance),
00174 (int) (multiplier * (pad_diameter + (2 * pad_solder_mask_clearance))),
00175 pin_pad_name,
00176 g_strdup_printf ("%d", pin_number),
00177 pad_flag
00178 );
00179 }
00180
00181
00182
00183 if (c2_state)
00184 {
00185 x0 = ((-c2 - pad_length + pad_width) / 2.0);
00186 x1 = ((-c2 + pad_length - pad_width) / 2.0);
00187 }
00188 if (g2_state)
00189 {
00190 x0 = ((-g2 + pad_width) / 2.0) - pad_length;
00191 x1 = ((-g2 - pad_width) / 2.0);
00192 }
00193 if (z2_state)
00194 {
00195 x0 = ((-z2 + pad_width) / 2.0);
00196 x1 = ((-z2 - pad_width) / 2.0) + pad_length;
00197 }
00198 i = 1;
00199 for (pin_number = ((count_x / 2) + 2.5);
00200 pin_number < ((count_x / 2) + 1.5 + count_y);
00201 pin_number++)
00202 {
00203 create_new_pad
00204 (
00205 element,
00206 (int) (multiplier * x0),
00207 (int) (multiplier * ((-count_y / 2) - 1 + i) * pitch_y),
00208 (int) (multiplier * x1),
00209 (int) (multiplier * ((-count_y / 2) - 1 + i) * pitch_y),
00210 (int) (multiplier * pad_width),
00211 (int) (multiplier * pad_clearance),
00212 (int) (multiplier * (pad_diameter + (2 * pad_solder_mask_clearance))),
00213 pin_pad_name,
00214 g_strdup_printf ("%d", pin_number),
00215 pad_flag
00216 );
00217 i++;
00218 }
00219
00220
00221
00222 if (c1_state)
00223 {
00224 y0 = ((c1 - pad_length + pad_width) / 2.0);
00225 y1 = ((c1 + pad_length - pad_width) / 2.0);
00226 }
00227 if (g1_state)
00228 {
00229 y0 = ((g1 + pad_width) / 2.0);
00230 y1 = ((g1 - pad_width) / 2.0) + pad_length;
00231 }
00232 if (z1_state)
00233 {
00234 y0 = ((z1 + pad_width) / 2.0) - pad_length;
00235 y1 = ((z1 - pad_width) / 2.0);
00236 }
00237 i = 1;
00238 for (pin_number = ((count_x / 2) + 2.5 + count_y);
00239 pin_number < ((count_x / 2) + 1.5 + count_y + count_x);
00240 pin_number++)
00241 {
00242 create_new_pad
00243 (
00244 element,
00245 (int) (multiplier * ((-count_x / 2) - 1 + i) * pitch_x),
00246 (int) (multiplier * y0),
00247 (int) (multiplier * ((-count_x / 2) - 1 + i) * pitch_x),
00248 (int) (multiplier * y1),
00249 (int) (multiplier * pad_width),
00250 (int) (multiplier * pad_clearance),
00251 (int) (multiplier * (pad_diameter + (2 * pad_solder_mask_clearance))),
00252 pin_pad_name,
00253 g_strdup_printf ("%d", pin_number),
00254 pad_flag
00255 );
00256 i++;
00257 }
00258
00259
00260
00261 if (c2_state)
00262 {
00263 x0 = ((c2 - pad_length + pad_width) / 2.0);
00264 x1 = ((c2 + pad_length - pad_width) / 2.0);
00265 }
00266 if (g2_state)
00267 {
00268 x0 = ((g2 + pad_width) / 2.0);
00269 x1 = ((g2 - pad_width) / 2.0) + pad_length;
00270 }
00271 if (z2_state)
00272 {
00273 x0 = ((z2 + pad_width) / 2.0) - pad_length;
00274 x1 = ((z2 - pad_width) / 2.0);
00275 }
00276 i = 1;
00277 for (pin_number = ((count_x / 2) + 2.5 + count_y + count_x);
00278 pin_number < ((count_x / 2) + 1.5 + (2 * count_y) + count_x);
00279 pin_number++)
00280 {
00281 create_new_pad
00282 (
00283 element,
00284 (int) (multiplier * x0),
00285 (int) (multiplier * ((count_y / 2) + 1 - i) * pitch_y),
00286 (int) (multiplier * x1),
00287 (int) (multiplier * ((count_y / 2) + 1 - i) * pitch_y),
00288 (int) (multiplier * pad_width),
00289 (int) (multiplier * pad_clearance),
00290 (int) (multiplier * (pad_diameter + (2 * pad_solder_mask_clearance))),
00291 pin_pad_name,
00292 g_strdup_printf ("%d", pin_number),
00293 pad_flag
00294 );
00295 i++;
00296 }
00297
00298
00299
00300 if (c1_state)
00301 {
00302 y0 = ((-c1 - pad_length + pad_width) / 2.0);
00303 y1 = ((-c1 + pad_length - pad_width) / 2.0);
00304 }
00305 if (g1_state)
00306 {
00307 y0 = ((-g1 + pad_width) / 2.0) - pad_length;
00308 y1 = ((-g1 - pad_width) / 2.0);
00309 }
00310 if (z1_state)
00311 {
00312 y0 = ((-z1 + pad_width) / 2.0);
00313 y1 = ((-z1 - pad_width) / 2.0) + pad_length;
00314 }
00315 i = 1;
00316 for (pin_number = ((count_x / 2) + 2.5 + (2 * count_y) + count_x);
00317 pin_number < (2 * (count_y + count_x) + 1);
00318 pin_number++)
00319 {
00320 create_new_pad
00321 (
00322 element,
00323 (int) (multiplier * ((count_x / 2) + 1 - i) * pitch_x),
00324 (int) (multiplier * y0),
00325 (int) (multiplier * ((count_x / 2) + 1 - i) * pitch_x),
00326 (int) (multiplier * y1),
00327 (int) (multiplier * pad_width),
00328 (int) (multiplier * pad_clearance),
00329 (int) (multiplier * (pad_diameter + (2 * pad_solder_mask_clearance))),
00330 pin_pad_name,
00331 g_strdup_printf ("%d", pin_number),
00332 pad_flag
00333 );
00334 i++;
00335 }
00336
00337 if (silkscreen_package_outline)
00338 {
00339
00340 create_new_line
00341 (
00342 element,
00343 (int) (multiplier * (package_body_length / 2.0)),
00344 (int) (multiplier * (-package_body_width / 2.0)),
00345 (int) (multiplier * (package_body_length / 2.0)),
00346 (int) (multiplier * (-1 * ((((count_y - 1) * pitch_y) + pad_length) / 2.0) - pad_solder_mask_clearance)),
00347 (int) (multiplier * (silkscreen_line_width))
00348 );
00349 create_new_line
00350 (
00351 element,
00352 (int) (multiplier * (package_body_length / 2.0)),
00353 (int) (multiplier * (-package_body_width / 2.0)),
00354 (int) (multiplier * (((((count_x - 1) * pitch_x) + pad_length) / 2.0) + pad_solder_mask_clearance)),
00355 (int) (multiplier * (-package_body_width / 2.0)),
00356 (int) (multiplier * (silkscreen_line_width))
00357 );
00358
00359 create_new_line
00360 (
00361 element,
00362 (int) (multiplier * (package_body_length / 2.0)),
00363 (int) (multiplier * (package_body_width / 2.0)),
00364 (int) (multiplier * (package_body_length / 2.0)),
00365 (int) (multiplier * (((((count_y - 1) * pitch_y) + pad_length) / 2.0) + pad_solder_mask_clearance)),
00366 (int) (multiplier * (silkscreen_line_width))
00367 );
00368 create_new_line
00369 (
00370 element,
00371 (int) (multiplier * (package_body_length / 2.0)),
00372 (int) (multiplier * (package_body_width / 2.0)),
00373 (int) (multiplier * (((((count_x - 1) * pitch_x) + pad_length) / 2.0) + pad_solder_mask_clearance)),
00374 (int) (multiplier * (package_body_width / 2.0)),
00375 (int) (multiplier * (silkscreen_line_width))
00376 );
00377
00378 create_new_line
00379 (
00380 element,
00381 (int) (multiplier * (-package_body_length / 2.0)),
00382 (int) (multiplier * (package_body_width / 2.0)),
00383 (int) (multiplier * (-package_body_length / 2.0)),
00384 (int) (multiplier * (((((count_y - 1) * pitch_y) + pad_length) / 2.0) + pad_solder_mask_clearance)),
00385 (int) (multiplier * (silkscreen_line_width))
00386 );
00387 create_new_line
00388 (
00389 element,
00390 (int) (multiplier * (-package_body_length / 2.0)),
00391 (int) (multiplier * (package_body_width / 2.0)),
00392 (int) (multiplier * (-1 * ((((count_x - 1) * pitch_x) + pad_length) / 2.0) - pad_solder_mask_clearance)),
00393 (int) (multiplier * (package_body_width / 2.0)),
00394 (int) (multiplier * (silkscreen_line_width))
00395 );
00396
00397 create_new_line
00398 (
00399 element,
00400 (int) (multiplier * (-1 * ((((count_x - 1) * pitch_x) + pad_length) / 2.0) - pad_solder_mask_clearance)),
00401 (int) (multiplier * (-package_body_width / 2.0)),
00402 (int) (multiplier * (-package_body_length / 2.0)),
00403 (int) (multiplier * (-1 * ((((count_y - 1) * pitch_y) + pad_length) / 2.0) - pad_solder_mask_clearance)),
00404 (int) (multiplier * (silkscreen_line_width))
00405 );
00406 }
00407
00408 if (silkscreen_indicate_1)
00409 {
00410 if (c1_state)
00411 {
00412 y_dot = ((-c1 + pad_length - pad_width) / 2.0) +
00413 pad_width + pad_solder_mask_clearance +
00414 (2 * silkscreen_line_width);
00415 }
00416 if (g1_state)
00417 {
00418 y_dot = ((-g1 - pad_width) / 2.0) +
00419 pad_width + pad_solder_mask_clearance +
00420 (2 * silkscreen_line_width);
00421 }
00422 if (z1_state)
00423 {
00424 y_dot = ((-z1 - pad_width) / 2.0) + pad_length +
00425 pad_width + pad_solder_mask_clearance +
00426 (2 * silkscreen_line_width);
00427 }
00428 create_new_arc
00429 (
00430 element,
00431 0,
00432 (int) (multiplier * y_dot),
00433 (int) (multiplier * 0.5 * silkscreen_line_width),
00434 (int) (multiplier * 0.5 * silkscreen_line_width),
00435 0,
00436 360,
00437 (int) (multiplier * silkscreen_line_width)
00438 );
00439 }
00440
00441 if (courtyard)
00442 {
00443 create_new_line
00444 (
00445 element,
00446 (int) (xmin),
00447 (int) (ymin),
00448 (int) (xmin),
00449 (int) (ymax),
00450 (int) (multiplier * courtyard_line_width)
00451 );
00452 create_new_line
00453 (
00454 element,
00455 (int) (xmax),
00456 (int) (ymin),
00457 (int) (xmax),
00458 (int) (ymax),
00459 (int) (multiplier * courtyard_line_width)
00460 );
00461 create_new_line
00462 (
00463 element,
00464 (int) (xmin),
00465 (int) (ymin),
00466 (int) (xmax),
00467 (int) (ymin),
00468 (int) (multiplier * courtyard_line_width)
00469 );
00470 create_new_line
00471 (
00472 element,
00473 (int) (xmax),
00474 (int) (ymax),
00475 (int) (xmin),
00476 (int) (ymax),
00477 (int) (multiplier * courtyard_line_width)
00478 );
00479 }
00480
00481 if (attributes_in_footprint)
00482 {
00483 element = create_attributes_in_element (element);
00484 }
00485
00486 if (verbose)
00487 {
00488 g_log ("", G_LOG_LEVEL_INFO,
00489 _("created an element for a %s package: %s."),
00490 footprint_type,
00491 footprint_filename);
00492 }
00493 current_element = (ElementTypePtr) &element;
00494 return (EXIT_SUCCESS);
00495 }
00496
00497
00507 int
00508 plcc_create_packages_list ()
00509 {
00510 g_list_free (packages_list);
00511 packages_list = g_list_append (packages_list, "PLCC");
00512 return (EXIT_SUCCESS);
00513 }
00514
00515
00545 int
00546 plcc_drc ()
00547 {
00548 int result = EXIT_SUCCESS;
00549 if (verbose)
00550 {
00551 g_log ("", G_LOG_LEVEL_INFO,
00552 (_("[%s] DRC Check: checking package %s.")),
00553 footprint_type, footprint_name);
00554 }
00555
00556 switch (pad_shapes_type)
00557 {
00558 case NO_SHAPE:
00559 {
00560 if (verbose)
00561 {
00562 g_log ("", G_LOG_LEVEL_WARNING,
00563 (_("[%s] DRC Error: NO_SHAPE specified for check for allowed pad shapes.")),
00564 footprint_type);
00565 }
00566 result = EXIT_FAILURE;
00567 break;
00568 }
00569 case ROUND:
00570 {
00571 if (verbose)
00572 {
00573 g_log ("", G_LOG_LEVEL_WARNING,
00574 (_("[%s] DRC Error: round pad shape specified for check for allowed pad shapes.")),
00575 footprint_type);
00576 }
00577 result = EXIT_FAILURE;
00578 break;
00579 }
00580 case SQUARE:
00581 {
00582 break;
00583 }
00584 case OCTAGONAL:
00585 {
00586 if (verbose)
00587 {
00588 g_log ("", G_LOG_LEVEL_WARNING,
00589 (_("[%s] DRC Error: octagonal pad shape specified for check for allowed pad shapes.")),
00590 footprint_type);
00591 }
00592 result = EXIT_FAILURE;
00593 break;
00594 }
00595 case ROUND_ELONGATED:
00596 {
00597 if (verbose)
00598 {
00599 g_log ("", G_LOG_LEVEL_WARNING,
00600 (_("[%s] DRC Error: round elongated pad shape specified for check for allowed pad shapes.")),
00601 footprint_type);
00602 }
00603 result = EXIT_FAILURE;
00604 break;
00605 }
00606 default:
00607 {
00608 if (verbose)
00609 {
00610 g_log ("", G_LOG_LEVEL_WARNING,
00611 (_("[%s] DRC Error: no valid pad shape type specified.")),
00612 footprint_type);
00613 }
00614 result = EXIT_FAILURE;
00615 break;
00616 }
00617 }
00618
00619 if (package_body_length <= 0.0)
00620 {
00621 if (verbose)
00622 {
00623 g_log ("", G_LOG_LEVEL_WARNING,
00624 (_("[%s] DRC Error: check for package body length is <= 0.0.")),
00625 footprint_type);
00626 }
00627 result = EXIT_FAILURE;
00628 }
00629 if (package_body_width <= 0.0)
00630 {
00631 if (verbose)
00632 {
00633 g_log ("", G_LOG_LEVEL_WARNING,
00634 (_("[%s] DRC Error: check for package body width is <= 0.0.")),
00635 footprint_type);
00636 }
00637 result = EXIT_FAILURE;
00638 }
00639 if (package_body_height <= 0.0)
00640 {
00641 if (verbose)
00642 {
00643 g_log ("", G_LOG_LEVEL_WARNING,
00644 (_("[%s] DRC Error: check for package body height is <= 0.0.")),
00645 footprint_type);
00646 }
00647 result = EXIT_FAILURE;
00648 }
00649
00650 if (courtyard_length <= 0.0)
00651 {
00652 if (verbose)
00653 {
00654 g_log ("", G_LOG_LEVEL_WARNING,
00655 (_("[%s] DRC Error: check for courtyard length is <= 0.0.")),
00656 footprint_type);
00657 }
00658 result = EXIT_FAILURE;
00659 }
00660 if (courtyard_width <= 0.0)
00661 {
00662 if (verbose)
00663 {
00664 g_log ("", G_LOG_LEVEL_WARNING,
00665 (_("[%s] DRC Error: check for courtyard width is <= 0.0.")),
00666 footprint_type);
00667 }
00668 result = EXIT_FAILURE;
00669 }
00670
00671 if (pitch_x - pad_diameter < pad_clearance)
00672 {
00673 if (verbose)
00674 {
00675 g_log ("", G_LOG_LEVEL_WARNING,
00676 (_("[%s] DRC Error: check for minimum clearance between copper (X-direction).")),
00677 footprint_type);
00678 }
00679 result = EXIT_FAILURE;
00680 }
00681
00682 if (pitch_y - pad_diameter < pad_clearance)
00683 {
00684 if (verbose)
00685 {
00686 g_log ("", G_LOG_LEVEL_WARNING,
00687 (_("[%s] DRC Error: check for minimum clearance between copper (Y-direction).")),
00688 footprint_type);
00689 }
00690 result = EXIT_FAILURE;
00691 }
00692
00693 if (fiducial)
00694 {
00695
00696 if (fiducial_pad_diameter == 0.0)
00697 {
00698 if (verbose)
00699 {
00700 g_log ("", G_LOG_LEVEL_WARNING,
00701 (_("[%s] DRC Error: check for zero width fiducial pad.")),
00702 footprint_type);
00703 }
00704 result = EXIT_FAILURE;
00705 }
00706
00707 if (fiducial_pad_solder_mask_clearance == 0.0)
00708 {
00709 if (verbose)
00710 {
00711 g_log ("", G_LOG_LEVEL_WARNING,
00712 (_("[%s] DRC Error: check for zero width solder mask clearance.")),
00713 footprint_type);
00714 }
00715 result = EXIT_FAILURE;
00716 }
00720
00721
00722 #if 0
00723 if ()
00724 {
00725 if (verbose)
00726 {
00727 g_log ("", G_LOG_LEVEL_WARNING,
00728 (_("[%s] DRC Error: check for distance between fiducial and nearest pad.")),
00729 footprint_type);
00730 }
00731 result = EXIT_FAILURE;
00732 }
00733 #endif
00734 }
00735
00736
00737 if (package_body_length - courtyard_length < courtyard_clearance_with_package)
00738 {
00739 if (verbose)
00740 {
00741 g_log ("", G_LOG_LEVEL_WARNING,
00742 (_("[%s] DRC Error: check for clearance of the package length with regard to the courtyard dimensions.")),
00743 footprint_type);
00744 }
00745 result = EXIT_FAILURE;
00746 }
00747
00748
00749 if (package_body_width - courtyard_width < courtyard_clearance_with_package)
00750 {
00751 if (verbose)
00752 {
00753 g_log ("", G_LOG_LEVEL_WARNING,
00754 (_("[%s] DRC Error: check for clearance of the package width with regard to the courtyard dimensions.")),
00755 footprint_type);
00756 }
00757 result = EXIT_FAILURE;
00758 }
00764
00765 if (silkscreen_package_outline && (silkscreen_line_width == 0.0))
00766 {
00767 if (verbose)
00768 {
00769 g_log ("", G_LOG_LEVEL_WARNING,
00770 (_("[%s] DRC Error: line width 0.0 specified for check for a reasonable silk line width.")),
00771 footprint_type);
00772 }
00773 result = EXIT_FAILURE;
00774 }
00775 switch (units_type)
00776 {
00777 case NO_UNITS:
00778 {
00779 if (verbose)
00780 {
00781 g_log ("", G_LOG_LEVEL_WARNING,
00782 (_("[%s] DRC Error: no units specified for check for a reasonable silk line width.")),
00783 footprint_type);
00784 }
00785 result = EXIT_FAILURE;
00786 break;
00787 }
00788 case MIL:
00789 if (silkscreen_package_outline && (silkscreen_line_width > 40.0))
00790 {
00791 if (verbose)
00792 {
00793 g_log ("", G_LOG_LEVEL_WARNING,
00794 (_("[%s] DRC Error: line width > 40.0 mil specified check for a reasonable silk line width.")),
00795 footprint_type);
00796 }
00797 result = EXIT_FAILURE;
00798 break;
00799 }
00800 case MIL_100:
00801 if (silkscreen_package_outline && (silkscreen_line_width > 4000.0))
00802 {
00803 if (verbose)
00804 {
00805 g_log ("", G_LOG_LEVEL_WARNING,
00806 (_("[%s] DRC Error: line width > 40.0 mil specified check for a reasonable silk line width.")),
00807 footprint_type);
00808 }
00809 result = EXIT_FAILURE;
00810 break;
00811 }
00812 case MM:
00813 if (silkscreen_package_outline && (silkscreen_line_width > 1.0))
00814 {
00815 if (verbose)
00816 {
00817 g_log ("", G_LOG_LEVEL_WARNING,
00818 (_("[%s] DRC Error: line width > 1.0 mm specified check for a reasonable silk line width.")),
00819 footprint_type);
00820 }
00821 result = EXIT_FAILURE;
00822 break;
00823 }
00824 default:
00825 {
00826 if (verbose)
00827 {
00828 g_log ("", G_LOG_LEVEL_WARNING,
00829 (_("[%s] DRC Error: no valid units type specified for check for a reasonable silk line width.")),
00830 footprint_type);
00831 }
00832 result = EXIT_FAILURE;
00833 break;
00834 }
00835 }
00836
00837 if (verbose && (result == EXIT_SUCCESS))
00838 {
00839 g_log ("", G_LOG_LEVEL_INFO,
00840 (_("[%s] DRC Check: no errors while checking package %s.")),
00841 footprint_type, footprint_name);
00842 }
00843 return (result);
00844 }
00845
00846
00860 int
00861 plcc_get_default_footprint_values ()
00862 {
00863 if (!strcmp (footprint_name, "?PLCC84"))
00864 {
00865 footprint_units = g_strdup ("mm");
00866 number_of_pins = 100;
00867 package_body_width = 11.00;
00868 package_body_length = 11.00;
00869 package_body_height = 1.40;
00870 package_is_radial = FALSE;
00871 number_of_columns = 10;
00872 number_of_rows = 10;
00873 pitch_x = 1.00;
00874 pitch_y = 1.00;
00875 count_x = 0;
00876 count_y = 0;
00877 pad_shape = g_strdup ("circular pad");
00878 pin_drill_diameter = 0.0;
00879 pad_diameter = 0.40;
00880 pad_clearance = 0.15;
00881 pad_solder_mask_clearance = 0.15;
00882 courtyard_length = 13.00;
00883 courtyard_width = 13.00;
00884 silkscreen_length = 11.00;
00885 silkscreen_width = 11.00;
00886 g_free (footprint_name);
00887 footprint_name = g_strdup ("PLCC84");
00888 return (EXIT_SUCCESS);
00889 }
00890 else
00891 {
00892 fprintf (stderr,
00893 _("WARNING: default values for footprint %s not found.\n"),
00894 footprint_name);
00895 return (EXIT_FAILURE);
00896 }
00897 }
00898
00899
00900 #if GUI
00901
00908 int
00909 plcc_set_gui_constraints ()
00910 {
00911
00912 GtkWidget *package_is_radial_checkbutton = lookup_widget (GTK_WIDGET (widget),
00913 "package_is_radial_checkbutton");
00914 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (package_is_radial_checkbutton), FALSE);
00915 gtk_widget_set_sensitive (package_is_radial_checkbutton, FALSE);
00916
00917
00918 GtkWidget *number_1_position_entry = lookup_widget (GTK_WIDGET (widget),
00919 "number_1_position_entry");
00920 gtk_combo_box_set_active (GTK_COMBO_BOX (number_1_position_entry), 4);
00921 gtk_widget_set_sensitive (number_1_position_entry, FALSE);
00922 GtkWidget *pad_diameter_entry = lookup_widget (GTK_WIDGET (widget),
00923 "pad_diameter_entry");
00924 gtk_entry_set_text (GTK_ENTRY (pad_diameter_entry), "");
00925 gtk_widget_set_sensitive (pad_diameter_entry, FALSE);
00926 GtkWidget *pin_drill_diameter_entry = lookup_widget (GTK_WIDGET (widget),
00927 "pin_drill_diameter_entry");
00928 gtk_entry_set_text (GTK_ENTRY (pin_drill_diameter_entry), "");
00929 gtk_widget_set_sensitive (pin_drill_diameter_entry, FALSE);
00930 GtkWidget *pad_shape_entry = lookup_widget (GTK_WIDGET (widget),
00931 "pad_shape_entry");
00932 gtk_combo_box_set_active (GTK_COMBO_BOX (pad_shape_entry), 2);
00933
00934
00935 gui_constraints_disable_thermal_tab_widgets (widget);
00936 return (EXIT_SUCCESS);
00937 }
00938 #endif
00939
00940
00947 int
00948 plcc_write_footprint ()
00949 {
00950 gdouble xmax;
00951 gdouble xmin;
00952 gdouble ymax;
00953 gdouble ymin;
00954 gdouble x_text;
00955 gdouble y_text;
00956 gint pin_number;
00957 gchar *pin_pad_name = g_strdup ("");
00958 gchar *pin_pad_flags = g_strdup ("");
00959 gint i;
00960 gdouble x0;
00961 gdouble x1;
00962 gdouble y0;
00963 gdouble y1;
00964 gdouble y_dot;
00965
00966
00967 fp = fopen (footprint_filename, "w");
00968 if (!fp)
00969 {
00970 g_log ("", G_LOG_LEVEL_WARNING,
00971 _("could not open file for %s footprint: %s."),
00972 footprint_type, footprint_filename);
00973 fclose (fp);
00974 return (EXIT_FAILURE);
00975 }
00976
00977 if (license_in_footprint)
00978 {
00979 write_license ();
00980 }
00981
00982
00983 if (c1_state)
00984 {
00985 ymin = multiplier * (((-c1 - pad_length) / 2.0) - pad_solder_mask_clearance);
00986 ymax = multiplier * (((c1 + pad_length) / 2.0) + pad_solder_mask_clearance);
00987 }
00988 if (g1_state)
00989 {
00990 ymin = multiplier * ((-g1 / 2.0) - pad_length - pad_solder_mask_clearance);
00991 ymax = multiplier * ((g1 / 2.0) + pad_length + pad_solder_mask_clearance);
00992 }
00993 if (z1_state)
00994 {
00995 ymin = multiplier * ((-z1 / 2.0) - pad_solder_mask_clearance);
00996 ymax = multiplier * ((z1 / 2.0) + pad_solder_mask_clearance);
00997 }
00998 if (c2_state)
00999 {
01000 xmin = multiplier * (((-c2 - pad_length) / 2.0) - pad_solder_mask_clearance);
01001 xmax = multiplier * (((c2 + pad_length) / 2.0) + pad_solder_mask_clearance);
01002 }
01003 if (g2_state)
01004 {
01005 xmin = multiplier * ((-g2 / 2.0) - pad_length - pad_solder_mask_clearance);
01006 xmax = multiplier * ((g2 / 2.0) + pad_length + pad_solder_mask_clearance);
01007 }
01008 if (z2_state)
01009 {
01010 xmin = multiplier * ((-z2 / 2.0) - pad_solder_mask_clearance);
01011 xmax = multiplier * ((z2 / 2.0) + pad_solder_mask_clearance);
01012 }
01013
01014
01015 if ((multiplier * ((-package_body_length / 2.0) - courtyard_clearance_with_package)) < xmin)
01016 xmin = (multiplier * ((-package_body_length / 2.0) - courtyard_clearance_with_package));
01017 if ((multiplier * ((package_body_length / 2.0) + courtyard_clearance_with_package)) > xmax)
01018 xmax = (multiplier * ((package_body_length / 2.0) + courtyard_clearance_with_package));
01019 if ((multiplier * ((-package_body_width / 2.0) - courtyard_clearance_with_package)) < ymin)
01020 ymin = (multiplier * ((-package_body_width / 2.0) - courtyard_clearance_with_package));
01021 if ((multiplier * ((package_body_width / 2.0) + courtyard_clearance_with_package)) > ymax)
01022 ymax = (multiplier * ((package_body_width / 2.0) + courtyard_clearance_with_package));
01023
01024 if (multiplier * (-courtyard_length / 2.0) < xmin)
01025 xmin = multiplier * (-courtyard_length / 2.0);
01026 if (multiplier * (courtyard_length / 2.0) > xmax)
01027 xmax = multiplier * (courtyard_length / 2.0);
01028 if (multiplier * (-courtyard_width / 2.0) < ymin)
01029 ymin = multiplier * (-courtyard_width / 2.0);
01030 if (multiplier * (courtyard_width / 2.0) > ymax)
01031 ymax = multiplier * (courtyard_width / 2.0);
01032
01033
01034 x_text = 0.0 ;
01035 y_text = (ymin - 10000.0);
01036 write_element_header (x_text, y_text);
01037
01038
01039
01040
01041 if (c1_state)
01042 {
01043 y0 = ((-c1 - pad_length + pad_width) / 2.0);
01044 y1 = ((-c1 + pad_length - pad_width) / 2.0);
01045 }
01046 if (g1_state)
01047 {
01048 y0 = ((-g1 + pad_width) / 2.0) - pad_length;
01049 y1 = ((-g1 - pad_width) / 2.0);
01050 }
01051 if (z1_state)
01052 {
01053 y0 = ((-z1 + pad_width) / 2.0);
01054 y1 = ((-z1 - pad_width) / 2.0) + pad_length;
01055 }
01056 for (pin_number = 1;
01057 pin_number < ((count_x / 2) + 1.5);
01058 pin_number++)
01059 {
01060 if (pin1_square && (pin_number == 1))
01061 pin_pad_flags = g_strdup ("square");
01062 else if (!strcmp (pad_shape, "rectangular pad"))
01063 pin_pad_flags = g_strdup ("square");
01064 else
01065 pin_pad_flags = g_strdup ("");
01066 write_pad
01067 (
01068 pin_number,
01069 pin_pad_name,
01070 multiplier * ((-pin_number + 1) * pitch_x),
01071 multiplier * y0,
01072 multiplier * ((-pin_number + 1) * pitch_x),
01073 multiplier * y1,
01074 multiplier * pad_width,
01075 multiplier * pad_clearance,
01076 multiplier * (pad_width + (2 * pad_solder_mask_clearance)),
01077 pin_pad_flags
01078 );
01079 }
01080
01081
01082
01083 if (c2_state)
01084 {
01085 x0 = ((-c2 - pad_length + pad_width) / 2.0);
01086 x1 = ((-c2 + pad_length - pad_width) / 2.0);
01087 }
01088 if (g2_state)
01089 {
01090 x0 = ((-g2 + pad_width) / 2.0) - pad_length;
01091 x1 = ((-g2 - pad_width) / 2.0);
01092 }
01093 if (z2_state)
01094 {
01095 x0 = ((-z2 + pad_width) / 2.0);
01096 x1 = ((-z2 - pad_width) / 2.0) + pad_length;
01097 }
01098 i = 1;
01099 for (pin_number = ((count_x / 2) + 2.5);
01100 pin_number < ((count_x / 2) + 1.5 + count_y);
01101 pin_number++)
01102 {
01103 write_pad
01104 (
01105 pin_number,
01106 pin_pad_name,
01107 multiplier * x0,
01108 multiplier * ((-count_y / 2) - 1 + i) * pitch_y,
01109 multiplier * x1,
01110 multiplier * ((-count_y / 2) - 1 + i) * pitch_y,
01111 multiplier * pad_width,
01112 multiplier * pad_clearance,
01113 multiplier * (pad_width + (2 * pad_solder_mask_clearance)),
01114 pin_pad_flags
01115 );
01116 i++;
01117 }
01118
01119
01120
01121 if (c1_state)
01122 {
01123 y0 = ((c1 - pad_length + pad_width) / 2.0);
01124 y1 = ((c1 + pad_length - pad_width) / 2.0);
01125 }
01126 if (g1_state)
01127 {
01128 y0 = ((g1 + pad_width) / 2.0);
01129 y1 = ((g1 - pad_width) / 2.0) + pad_length;
01130 }
01131 if (z1_state)
01132 {
01133 y0 = ((z1 + pad_width) / 2.0) - pad_length;
01134 y1 = ((z1 - pad_width) / 2.0);
01135 }
01136 i = 1;
01137 for (pin_number = ((count_x / 2) + 2.5 + count_y);
01138 pin_number < ((count_x / 2) + 1.5 + count_y + count_x);
01139 pin_number++)
01140 {
01141 write_pad
01142 (
01143 pin_number,
01144 pin_pad_name,
01145 multiplier * ((-count_x / 2) - 1 + i) * pitch_x,
01146 multiplier * y0,
01147 multiplier * ((-count_x / 2) - 1 + i) * pitch_x,
01148 multiplier * y1,
01149 multiplier * pad_width,
01150 multiplier * pad_clearance,
01151 multiplier * (pad_width + (2 * pad_solder_mask_clearance)),
01152 pin_pad_flags
01153 );
01154 i++;
01155 }
01156
01157
01158
01159 if (c2_state)
01160 {
01161 x0 = ((c2 - pad_length + pad_width) / 2.0);
01162 x1 = ((c2 + pad_length - pad_width) / 2.0);
01163 }
01164 if (g2_state)
01165 {
01166 x0 = ((g2 + pad_width) / 2.0);
01167 x1 = ((g2 - pad_width) / 2.0) + pad_length;
01168 }
01169 if (z2_state)
01170 {
01171 x0 = ((z2 + pad_width) / 2.0) - pad_length;
01172 x1 = ((z2 - pad_width) / 2.0);
01173 }
01174 i = 1;
01175 for (pin_number = ((count_x / 2) + 2.5 + count_y + count_x);
01176 pin_number < ((count_x / 2) + 1.5 + (2 * count_y) + count_x);
01177 pin_number++)
01178 {
01179 write_pad
01180 (
01181 pin_number,
01182 pin_pad_name,
01183 multiplier * x0,
01184 multiplier * ((count_y / 2) + 1 - i) * pitch_y,
01185 multiplier * x1,
01186 multiplier * ((count_y / 2) + 1 - i) * pitch_y,
01187 multiplier * pad_width,
01188 multiplier * pad_clearance,
01189 multiplier * (pad_width + (2 * pad_solder_mask_clearance)),
01190 pin_pad_flags
01191 );
01192 i++;
01193 }
01194
01195
01196
01197 if (c1_state)
01198 {
01199 y0 = ((-c1 - pad_length + pad_width) / 2.0);
01200 y1 = ((-c1 + pad_length - pad_width) / 2.0);
01201 }
01202 if (g1_state)
01203 {
01204 y0 = ((-g1 + pad_width) / 2.0) - pad_length;
01205 y1 = ((-g1 - pad_width) / 2.0);
01206 }
01207 if (z1_state)
01208 {
01209 y0 = ((-z1 + pad_width) / 2.0);
01210 y1 = ((-z1 - pad_width) / 2.0) + pad_length;
01211 }
01212 i = 1;
01213 for (pin_number = ((count_x / 2) + 2.5 + (2 * count_y) + count_x);
01214 pin_number < (2 * (count_y + count_x) + 1);
01215 pin_number++)
01216 {
01217 write_pad
01218 (
01219 pin_number,
01220 pin_pad_name,
01221 multiplier * ((count_x / 2) + 1 - i) * pitch_x,
01222 multiplier * y0,
01223 multiplier * ((count_x / 2) + 1 - i) * pitch_x,
01224 multiplier * y1,
01225 multiplier * pad_width,
01226 multiplier * pad_clearance,
01227 multiplier * (pad_width + (2 * pad_solder_mask_clearance)),
01228 pin_pad_flags
01229 );
01230 i++;
01231 }
01232
01233 if (silkscreen_package_outline)
01234 {
01235 fprintf (fp, "# Write a package body on the silkscreen\n");
01236
01237 write_element_line
01238 (
01239 multiplier * (package_body_length / 2.0),
01240 multiplier * (-package_body_width / 2.0),
01241 multiplier * (package_body_length / 2.0),
01242 multiplier * (-1 * ((((count_y - 1) * pitch_y) + pad_length) / 2.0) - pad_solder_mask_clearance),
01243 multiplier * silkscreen_line_width
01244 );
01245 write_element_line
01246 (
01247 multiplier * (package_body_length / 2.0),
01248 multiplier * (-package_body_width / 2.0),
01249 multiplier * (((((count_x - 1) * pitch_x) + pad_length) / 2.0) + pad_solder_mask_clearance),
01250 multiplier * (-package_body_width / 2.0),
01251 multiplier * silkscreen_line_width
01252 );
01253
01254 write_element_line
01255 (
01256 multiplier * (package_body_length / 2.0),
01257 multiplier * (package_body_width / 2.0),
01258 multiplier * (package_body_length / 2.0),
01259 multiplier * (((((count_y - 1) * pitch_y) + pad_length) / 2.0) + pad_solder_mask_clearance),
01260 multiplier * silkscreen_line_width
01261 );
01262 write_element_line
01263 (
01264 multiplier * (package_body_length / 2.0),
01265 multiplier * (package_body_width / 2.0),
01266 multiplier * (((((count_x - 1) * pitch_x) + pad_length) / 2.0) + pad_solder_mask_clearance),
01267 multiplier * (package_body_width / 2.0),
01268 multiplier * silkscreen_line_width
01269 );
01270
01271 write_element_line
01272 (
01273 multiplier * (-package_body_length / 2.0),
01274 multiplier * (package_body_width / 2.0),
01275 multiplier * (-package_body_length / 2.0),
01276 multiplier * (((((count_y - 1) * pitch_y) + pad_length) / 2.0) + pad_solder_mask_clearance),
01277 multiplier * silkscreen_line_width
01278 );
01279 write_element_line
01280 (
01281 multiplier * (-package_body_length / 2.0),
01282 multiplier * (package_body_width / 2.0),
01283 multiplier * (-1 * ((((count_x - 1) * pitch_x) + pad_length) / 2.0) - pad_solder_mask_clearance),
01284 multiplier * (package_body_width / 2.0),
01285 multiplier * silkscreen_line_width
01286 );
01287
01288 write_element_line
01289 (
01290 multiplier * (-1 * ((((count_x - 1) * pitch_x) + pad_length) / 2.0) - pad_solder_mask_clearance),
01291 multiplier * (-package_body_width / 2.0),
01292 multiplier * (-package_body_length / 2.0),
01293 multiplier * (-1 * ((((count_y - 1) * pitch_y) + pad_length) / 2.0) - pad_solder_mask_clearance),
01294 multiplier * silkscreen_line_width
01295 );
01296 }
01297
01298 if (silkscreen_indicate_1)
01299 {
01300 fprintf (fp, "# Write a pin 1 marker on the silkscreen\n");
01301 if (c1_state)
01302 {
01303 y_dot = ((-c1 + pad_length - pad_width) / 2.0) +
01304 pad_width + pad_solder_mask_clearance +
01305 (2 * silkscreen_line_width);
01306 }
01307 if (g1_state)
01308 {
01309 y_dot = ((-g1 - pad_width) / 2.0) +
01310 pad_width + pad_solder_mask_clearance +
01311 (2 * silkscreen_line_width);
01312 }
01313 if (z1_state)
01314 {
01315 y_dot = ((-z1 - pad_width) / 2.0) + pad_length +
01316 pad_width + pad_solder_mask_clearance +
01317 (2 * silkscreen_line_width);
01318 }
01319 write_element_arc
01320 (
01321 0,
01322 multiplier * y_dot,
01323 multiplier * 0.5 * silkscreen_line_width,
01324 multiplier * 0.5 * silkscreen_line_width,
01325 0,
01326 360,
01327 multiplier * silkscreen_line_width
01328 );
01329 }
01330
01331 if (courtyard)
01332 {
01333 fprintf (fp, "# Write a courtyard on the silkscreen\n");
01334 write_rectangle
01335 (
01336 xmin,
01337 ymin,
01338 xmax,
01339 ymax,
01340 multiplier * courtyard_line_width
01341 );
01342 }
01343
01344 if (attributes_in_footprint)
01345 {
01346 write_attributes ();
01347 }
01348
01349 fprintf (fp, "\n");
01350 fprintf (fp, ")\n");
01351 fclose (fp);
01352
01353 if (verbose)
01354 {
01355 g_log ("", G_LOG_LEVEL_INFO,
01356 _("wrote a footprint for a %s package: %s."),
01357 footprint_type,
01358 footprint_filename);
01359 }
01360 return (EXIT_SUCCESS);
01361 }
01362
01363
01367 static fpw_function_t
01368 plcc_function_list[] =
01369 {
01370 #if GUI
01371 {
01372 "Set GUI constraints",
01373 plcc_set_gui_constraints,
01374 "Set GUI constraints for a PLCC package",
01375 NULL
01376 },
01377 #endif
01378 {
01379 "Create element",
01380 plcc_create_element,
01381 "Create an element for a PLCC package",
01382 NULL
01383 },
01384 {
01385 "Create Packages List",
01386 plcc_create_packages_list,
01387 "Create a list of known PLCC packages",
01388 NULL
01389 },
01390 {
01391 "DRC PLCC Element",
01392 plcc_drc,
01393 "Design Rule Check for a PLCC package",
01394 NULL
01395 },
01396 {
01397 "Default Element Values",
01398 plcc_get_default_footprint_values,
01399 "Get default values for a PLCC package",
01400 NULL
01401 },
01402 {
01403 "Write footprint",
01404 plcc_write_footprint,
01405 "Write a footprint for a PLCC package",
01406 NULL
01407 }
01408 };
01409
01410
01414 REGISTER_FUNCTIONS (plcc_function_list)
01415
01416
01417
01420 void
01421 plcc_init ()
01422 {
01423 register_plcc_function_list ();
01424 }
01425
01426
01427