Implement max hole size DRC checks.

Fixes https://gitlab.com/kicad/code/kicad/issues/6893
This commit is contained in:
Jeff Young 2021-01-03 22:57:51 +00:00
parent 710e621c6a
commit 7378c2c3b3
3 changed files with 82 additions and 36 deletions

View File

@ -101,9 +101,9 @@ DRC_ITEM DRC_ITEM::annularWidth( DRCE_ANNULAR_WIDTH,
_( "Annular width" ), _( "Annular width" ),
wxT( "annular_width" ) ); wxT( "annular_width" ) );
DRC_ITEM DRC_ITEM::drillTooSmall( DRCE_TOO_SMALL_DRILL, DRC_ITEM DRC_ITEM::drillTooSmall( DRCE_DRILL_OUT_OF_RANGE,
_( "Drill too small" ), _( "Drill out of range" ),
wxT( "drill_too_small" ) ); wxT( "drill_out_of_range" ) );
DRC_ITEM DRC_ITEM::viaDiameter( DRCE_VIA_DIAMETER, DRC_ITEM DRC_ITEM::viaDiameter( DRCE_VIA_DIAMETER,
_( "Via diameter" ), _( "Via diameter" ),
@ -113,9 +113,9 @@ DRC_ITEM DRC_ITEM::padstack( DRCE_PADSTACK,
_( "Padstack is not valid" ), _( "Padstack is not valid" ),
wxT( "padstack" ) ); wxT( "padstack" ) );
DRC_ITEM DRC_ITEM::microviaDrillTooSmall( DRCE_TOO_SMALL_MICROVIA_DRILL, DRC_ITEM DRC_ITEM::microviaDrillTooSmall( DRCE_MICROVIA_DRILL_OUT_OF_RANGE,
_( "Micro via drill too small" ), _( "Micro via drill out of range" ),
wxT( "microvia_drill_too_small" ) ); wxT( "microvia_drill_out_of_range" ) );
DRC_ITEM DRC_ITEM::courtyardsOverlap( DRCE_OVERLAPPING_FOOTPRINTS, DRC_ITEM DRC_ITEM::courtyardsOverlap( DRCE_OVERLAPPING_FOOTPRINTS,
_( "Courtyards overlap" ), _( "Courtyards overlap" ),
@ -260,10 +260,10 @@ std::shared_ptr<DRC_ITEM> DRC_ITEM::Create( int aErrorCode )
case DRCE_HOLE_CLEARANCE: return std::make_shared<DRC_ITEM>( holeClearance ); case DRCE_HOLE_CLEARANCE: return std::make_shared<DRC_ITEM>( holeClearance );
case DRCE_TRACK_WIDTH: return std::make_shared<DRC_ITEM>( trackWidth ); case DRCE_TRACK_WIDTH: return std::make_shared<DRC_ITEM>( trackWidth );
case DRCE_ANNULAR_WIDTH: return std::make_shared<DRC_ITEM>( annularWidth ); case DRCE_ANNULAR_WIDTH: return std::make_shared<DRC_ITEM>( annularWidth );
case DRCE_TOO_SMALL_DRILL: return std::make_shared<DRC_ITEM>( drillTooSmall ); case DRCE_DRILL_OUT_OF_RANGE: return std::make_shared<DRC_ITEM>( drillTooSmall );
case DRCE_VIA_DIAMETER: return std::make_shared<DRC_ITEM>( viaDiameter ); case DRCE_VIA_DIAMETER: return std::make_shared<DRC_ITEM>( viaDiameter );
case DRCE_PADSTACK: return std::make_shared<DRC_ITEM>( padstack ); case DRCE_PADSTACK: return std::make_shared<DRC_ITEM>( padstack );
case DRCE_TOO_SMALL_MICROVIA_DRILL: return std::make_shared<DRC_ITEM>( microviaDrillTooSmall ); case DRCE_MICROVIA_DRILL_OUT_OF_RANGE: return std::make_shared<DRC_ITEM>( microviaDrillTooSmall );
case DRCE_OVERLAPPING_FOOTPRINTS: return std::make_shared<DRC_ITEM>( courtyardsOverlap ); case DRCE_OVERLAPPING_FOOTPRINTS: return std::make_shared<DRC_ITEM>( courtyardsOverlap );
case DRCE_MISSING_COURTYARD: return std::make_shared<DRC_ITEM>( missingCourtyard ); case DRCE_MISSING_COURTYARD: return std::make_shared<DRC_ITEM>( missingCourtyard );
case DRCE_MALFORMED_COURTYARD: return std::make_shared<DRC_ITEM>( malformedCourtyard ); case DRCE_MALFORMED_COURTYARD: return std::make_shared<DRC_ITEM>( malformedCourtyard );

View File

@ -47,10 +47,10 @@ enum PCB_DRC_CODE {
DRCE_HOLE_CLEARANCE, // DRCE_HOLE_CLEARANCE, //
DRCE_TRACK_WIDTH, // Track width is too small or too large DRCE_TRACK_WIDTH, // Track width is too small or too large
DRCE_ANNULAR_WIDTH, // Via size and drill leave annulus too small or too large DRCE_ANNULAR_WIDTH, // Via size and drill leave annulus too small or too large
DRCE_TOO_SMALL_DRILL, // Too small via or pad drill DRCE_DRILL_OUT_OF_RANGE, // Too small via or pad drill
DRCE_VIA_DIAMETER, // Via diameter checks (min/max) DRCE_VIA_DIAMETER, // Via diameter checks (min/max)
DRCE_PADSTACK, // something is wrong with a pad or via stackup DRCE_PADSTACK, // something is wrong with a pad or via stackup
DRCE_TOO_SMALL_MICROVIA_DRILL, // Too small micro via drill DRCE_MICROVIA_DRILL_OUT_OF_RANGE, // Too small micro via drill
DRCE_OVERLAPPING_FOOTPRINTS, // footprint courtyards overlap DRCE_OVERLAPPING_FOOTPRINTS, // footprint courtyards overlap
DRCE_MISSING_COURTYARD, // footprint has no courtyard defined DRCE_MISSING_COURTYARD, // footprint has no courtyard defined
DRCE_MALFORMED_COURTYARD, // footprint has a courtyard but malformed DRCE_MALFORMED_COURTYARD, // footprint has a courtyard but malformed

View File

@ -23,7 +23,6 @@
#include <pad.h> #include <pad.h>
#include <track.h> #include <track.h>
#include <drc/drc_engine.h>
#include <drc/drc_item.h> #include <drc/drc_item.h>
#include <drc/drc_rule.h> #include <drc/drc_rule.h>
#include <drc/drc_test_provider_clearance_base.h> #include <drc/drc_test_provider_clearance_base.h>
@ -32,10 +31,8 @@
/* /*
Drilled hole size test. scans vias/through-hole pads and checks for min drill sizes Drilled hole size test. scans vias/through-hole pads and checks for min drill sizes
Errors generated: Errors generated:
- DRCE_TOO_SMALL_DRILL - DRCE_DRILL_OUT_OF_RANGE
- DRCE_TOO_SMALL_MICROVIA_DRILL - DRCE_MICROVIA_DRILL_OUT_OF_RANGE
TODO: max drill size check
*/ */
class DRC_TEST_PROVIDER_HOLE_SIZE : public DRC_TEST_PROVIDER class DRC_TEST_PROVIDER_HOLE_SIZE : public DRC_TEST_PROVIDER
@ -83,12 +80,12 @@ bool DRC_TEST_PROVIDER_HOLE_SIZE::Run()
for( FOOTPRINT* footprint : m_board->Footprints() ) for( FOOTPRINT* footprint : m_board->Footprints() )
{ {
if( m_drcEngine->IsErrorLimitExceeded( DRCE_TOO_SMALL_DRILL ) ) if( m_drcEngine->IsErrorLimitExceeded( DRCE_DRILL_OUT_OF_RANGE ) )
break; break;
for( PAD* pad : footprint->Pads() ) for( PAD* pad : footprint->Pads() )
{ {
if( m_drcEngine->IsErrorLimitExceeded( DRCE_TOO_SMALL_DRILL ) ) if( m_drcEngine->IsErrorLimitExceeded( DRCE_DRILL_OUT_OF_RANGE ) )
break; break;
checkPad( pad ); checkPad( pad );
@ -109,8 +106,8 @@ bool DRC_TEST_PROVIDER_HOLE_SIZE::Run()
for( VIA* via : vias ) for( VIA* via : vias )
{ {
bool exceedMicro = m_drcEngine->IsErrorLimitExceeded( DRCE_TOO_SMALL_MICROVIA_DRILL ); bool exceedMicro = m_drcEngine->IsErrorLimitExceeded( DRCE_MICROVIA_DRILL_OUT_OF_RANGE );
bool exceedStd = m_drcEngine->IsErrorLimitExceeded( DRCE_TOO_SMALL_DRILL ); bool exceedStd = m_drcEngine->IsErrorLimitExceeded( DRCE_DRILL_OUT_OF_RANGE );
if( exceedMicro && exceedStd ) if( exceedMicro && exceedStd )
break; break;
@ -126,24 +123,49 @@ bool DRC_TEST_PROVIDER_HOLE_SIZE::Run()
void DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( PAD* aPad ) void DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( PAD* aPad )
{ {
int holeSize = std::min( aPad->GetDrillSize().x, aPad->GetDrillSize().y ); int holeMinor = std::min( aPad->GetDrillSize().x, aPad->GetDrillSize().y );
int holeMajor = std::max( aPad->GetDrillSize().x, aPad->GetDrillSize().y );
if( holeSize == 0 ) if( holeMinor == 0 )
return; return;
auto constraint = m_drcEngine->EvalRulesForItems( HOLE_SIZE_CONSTRAINT, aPad ); auto constraint = m_drcEngine->EvalRulesForItems( HOLE_SIZE_CONSTRAINT, aPad );
int minHole = constraint.GetValue().Min(); bool fail_min = false;
bool fail_max = false;
int constraintValue;
accountCheck( constraint ); accountCheck( constraint );
if( holeSize < minHole ) if( constraint.Value().HasMin() && holeMinor < constraint.Value().Min() )
{ {
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_TOO_SMALL_DRILL ); fail_min = true;
constraintValue = constraint.Value().Min();
}
m_msg.Printf( _( "(%s %s; actual %s)" ), if( constraint.Value().HasMax() && holeMajor > constraint.Value().Max() )
{
fail_max = true;
constraintValue = constraint.Value().Max();
}
if( fail_min || fail_max )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_DRILL_OUT_OF_RANGE );
if( fail_min )
{
m_msg.Printf( _( "(%s min width %s; actual %s)" ),
constraint.GetName(), constraint.GetName(),
MessageTextFromValue( userUnits(), minHole ), MessageTextFromValue( userUnits(), constraintValue ),
MessageTextFromValue( userUnits(), holeSize ) ); MessageTextFromValue( userUnits(), holeMinor ) );
}
else
{
m_msg.Printf( _( "(%s max width %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), constraintValue ),
MessageTextFromValue( userUnits(), holeMajor ) );
}
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg ); drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
drcItem->SetItems( aPad ); drcItem->SetItems( aPad );
@ -163,29 +185,53 @@ void DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via, bool aExceedMicro, bool aE
if( aExceedMicro ) if( aExceedMicro )
return; return;
errorCode = DRCE_TOO_SMALL_MICROVIA_DRILL; errorCode = DRCE_MICROVIA_DRILL_OUT_OF_RANGE;
} }
else else
{ {
if( aExceedStd ) if( aExceedStd )
return; return;
errorCode = DRCE_TOO_SMALL_DRILL; errorCode = DRCE_DRILL_OUT_OF_RANGE;
} }
auto constraint = m_drcEngine->EvalRulesForItems( HOLE_SIZE_CONSTRAINT, via ); auto constraint = m_drcEngine->EvalRulesForItems( HOLE_SIZE_CONSTRAINT, via );
int minHole = constraint.GetValue().Min(); bool fail_min = false;
bool fail_max = false;
int constraintValue;
accountCheck( constraint ); accountCheck( constraint );
if( via->GetDrillValue() < minHole ) if( constraint.Value().HasMin() && via->GetDrillValue() < constraint.Value().Min() )
{
fail_min = true;
constraintValue = constraint.Value().Min();
}
if( constraint.Value().HasMax() && via->GetDrillValue() > constraint.Value().Max() )
{
fail_max = true;
constraintValue = constraint.Value().Max();
}
if( fail_min || fail_max )
{ {
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( errorCode ); std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( errorCode );
m_msg.Printf( _( "(%s %s; actual %s)" ), if( fail_min )
{
m_msg.Printf( _( "(%s min width %s; actual %s)" ),
constraint.GetName(), constraint.GetName(),
MessageTextFromValue( userUnits(), minHole ), MessageTextFromValue( userUnits(), constraintValue ),
MessageTextFromValue( userUnits(), via->GetDrillValue() ) ); MessageTextFromValue( userUnits(), via->GetDrillValue() ) );
}
else
{
m_msg.Printf( _( "(%s max width %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), constraintValue ),
MessageTextFromValue( userUnits(), via->GetDrillValue() ) );
}
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg ); drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
drcItem->SetItems( via ); drcItem->SetItems( via );