From fdb23d1a2d0d19dc73fb0bdb06a1d33c7b4a163f Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Thu, 30 Jul 2020 21:41:52 +0100 Subject: [PATCH] Add DRC check for items (pads for now) shorting two nets. Fixes https://gitlab.com/kicad/code/kicad/issues/4955 --- pcbnew/drc/drc.cpp | 16 ++++++++++++---- pcbnew/drc/drc.h | 1 + pcbnew/drc/drc_item.cpp | 6 ++++++ pcbnew/drc/drc_item.h | 1 + qa/drc_proto/drc_engine.h | 1 + qa/drc_proto/drc_item.cpp | 6 ++++++ qa/drc_proto/drc_item.h | 1 + .../drc_test_provider_copper_clearance.cpp | 16 ++++++++++++---- 8 files changed, 40 insertions(+), 8 deletions(-) diff --git a/pcbnew/drc/drc.cpp b/pcbnew/drc/drc.cpp index 703ce12426..30e4a008ab 100644 --- a/pcbnew/drc/drc.cpp +++ b/pcbnew/drc/drc.cpp @@ -1192,12 +1192,20 @@ bool DRC::doPadToPadsDrc( BOARD_COMMIT& aCommit, D_PAD* aRefPad, D_PAD** aStart, if( pad->GetParent() == aRefPad->GetParent() ) { // and have the same pad number ( equivalent pads ) - - // one can argue that this 2nd test is not necessary, that any - // two pads from a single module are acceptable. This 2nd test - // should eventually be a configuration option. if( pad->PadNameEqual( aRefPad ) ) + { + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_SHORTING_ITEMS ); + + m_msg.Printf( drcItem->GetErrorText() + _( " (nets %s and %s)" ), + pad->GetNetname(), aRefPad->GetNetname() ); + + drcItem->SetErrorMessage( m_msg ); + drcItem->SetItems( pad, aRefPad ); + + MARKER_PCB* marker = new MARKER_PCB( drcItem, aRefPad->GetPosition() ); + addMarkerToPcb( aCommit, marker ); continue; + } } // if either pad has no drill and is only on technical layers, not a clearance violation diff --git a/pcbnew/drc/drc.h b/pcbnew/drc/drc.h index 10f88b15c5..eb0e1eb339 100644 --- a/pcbnew/drc/drc.h +++ b/pcbnew/drc/drc.h @@ -40,6 +40,7 @@ enum PCB_DRC_CODE { DRCE_FIRST = 1, DRCE_UNCONNECTED_ITEMS = DRCE_FIRST, ///< items are unconnected + DRCE_SHORTING_ITEMS, ///< items short two nets but are not a net tie DRCE_ALLOWED_ITEMS, ///< a disallowed item has been used DRCE_CLEARANCE, ///< items are too close together DRCE_TRACKS_CROSSING, ///< tracks are crossing diff --git a/pcbnew/drc/drc_item.cpp b/pcbnew/drc/drc_item.cpp index 9bbf139600..90125b9ddf 100644 --- a/pcbnew/drc/drc_item.cpp +++ b/pcbnew/drc/drc_item.cpp @@ -43,6 +43,10 @@ DRC_ITEM DRC_ITEM::unconnectedItems( DRCE_UNCONNECTED_ITEMS, _( "Unconnected items" ), wxT( "unconnected_items" ) ); +DRC_ITEM DRC_ITEM::shortingItems( DRCE_SHORTING_ITEMS, + _( "Items shorting two nets" ), + wxT( "shorting_items" ) ); + DRC_ITEM DRC_ITEM::itemsNotAllowed( DRCE_ALLOWED_ITEMS, _( "Items not allowed" ), wxT( "items_not_allowed" ) ); @@ -162,6 +166,7 @@ DRC_ITEM DRC_ITEM::unresolvedVariable( DRCE_UNRESOLVED_VARIABLE, std::vector> DRC_ITEM::allItemTypes( { DRC_ITEM::unconnectedItems, + DRC_ITEM::shortingItems, DRC_ITEM::itemsNotAllowed, DRC_ITEM::clearance, DRC_ITEM::tracksCrossing, @@ -199,6 +204,7 @@ DRC_ITEM* DRC_ITEM::Create( int aErrorCode ) switch( aErrorCode ) { case DRCE_UNCONNECTED_ITEMS: return new DRC_ITEM( unconnectedItems ); + case DRCE_SHORTING_ITEMS: return new DRC_ITEM( shortingItems ); case DRCE_ALLOWED_ITEMS: return new DRC_ITEM( itemsNotAllowed ); case DRCE_CLEARANCE: return new DRC_ITEM( clearance ); case DRCE_TRACKS_CROSSING: return new DRC_ITEM( tracksCrossing ); diff --git a/pcbnew/drc/drc_item.h b/pcbnew/drc/drc_item.h index 1a0d286649..e61bab8b41 100644 --- a/pcbnew/drc/drc_item.h +++ b/pcbnew/drc/drc_item.h @@ -69,6 +69,7 @@ private: static std::vector> allItemTypes; static DRC_ITEM unconnectedItems; + static DRC_ITEM shortingItems; static DRC_ITEM itemsNotAllowed; static DRC_ITEM clearance; static DRC_ITEM tracksCrossing; diff --git a/qa/drc_proto/drc_engine.h b/qa/drc_proto/drc_engine.h index 3450b045ff..e3f65a0bad 100644 --- a/qa/drc_proto/drc_engine.h +++ b/qa/drc_proto/drc_engine.h @@ -67,6 +67,7 @@ enum PCB_DRC_CODE { DRCE_FIRST = 1, DRCE_UNCONNECTED_ITEMS = DRCE_FIRST, ///< items are unconnected + DRCE_SHORTING_ITEMS, ///< items shorting two nets but not a net-tie DRCE_ALLOWED_ITEMS, ///< a disallowed item has been used DRCE_CLEARANCE, ///< items are too close together DRCE_TRACKS_CROSSING, ///< tracks are crossing diff --git a/qa/drc_proto/drc_item.cpp b/qa/drc_proto/drc_item.cpp index 833bd96060..41ef7f602d 100644 --- a/qa/drc_proto/drc_item.cpp +++ b/qa/drc_proto/drc_item.cpp @@ -40,6 +40,10 @@ test::DRC_ITEM test::DRC_ITEM::unconnectedItems( DRCE_UNCONNECTED_ITEMS, _( "Unconnected items" ), wxT( "unconnected_items" ) ); +test::DRC_ITEM test::DRC_ITEM::shortingItems( DRCE_SHORTING_ITEMS, + _( "Items shorting two nets" ), + wxT( "shorting_items" ) ); + test::DRC_ITEM test::DRC_ITEM::itemsNotAllowed( DRCE_ALLOWED_ITEMS, _( "Items not allowed" ), wxT( "items_not_allowed" ) ); @@ -159,6 +163,7 @@ test::DRC_ITEM test::DRC_ITEM::unresolvedVariable( DRCE_UNRESOLVED_VARIABLE, std::vector> test::DRC_ITEM::allItemTypes( { DRC_ITEM::unconnectedItems, + DRC_ITEM::shortingItems, DRC_ITEM::itemsNotAllowed, DRC_ITEM::clearance, DRC_ITEM::tracksCrossing, @@ -196,6 +201,7 @@ test::DRC_ITEM* test::DRC_ITEM::Create( int aErrorCode ) switch( aErrorCode ) { case DRCE_UNCONNECTED_ITEMS: return new DRC_ITEM( unconnectedItems ); + case DRCE_SHORTING_ITEMS: return new DRC_ITEM( shortingItems ); case DRCE_ALLOWED_ITEMS: return new DRC_ITEM( itemsNotAllowed ); case DRCE_CLEARANCE: return new DRC_ITEM( clearance ); case DRCE_TRACKS_CROSSING: return new DRC_ITEM( tracksCrossing ); diff --git a/qa/drc_proto/drc_item.h b/qa/drc_proto/drc_item.h index 102c607d34..bfc6dc27de 100644 --- a/qa/drc_proto/drc_item.h +++ b/qa/drc_proto/drc_item.h @@ -86,6 +86,7 @@ private: static std::vector> allItemTypes; static DRC_ITEM unconnectedItems; + static DRC_ITEM shortingItems; static DRC_ITEM itemsNotAllowed; static DRC_ITEM clearance; static DRC_ITEM tracksCrossing; diff --git a/qa/drc_proto/drc_test_provider_copper_clearance.cpp b/qa/drc_proto/drc_test_provider_copper_clearance.cpp index 99b6c52398..e5448bffa4 100644 --- a/qa/drc_proto/drc_test_provider_copper_clearance.cpp +++ b/qa/drc_proto/drc_test_provider_copper_clearance.cpp @@ -603,12 +603,20 @@ bool test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D if( pad->GetParent() == aRefPad->GetParent() ) { // and have the same pad number ( equivalent pads ) - - // one can argue that this 2nd test is not necessary, that any - // two pads from a single module are acceptable. This 2nd test - // should eventually be a configuration option. if( pad->PadNameEqual( aRefPad ) ) + { + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_SHORTING_ITEMS ); + wxString msg; + msg.Printf( drcItem->GetErrorText() + _( " (nets %s and %s)" ), + pad->GetNetCode(), aRefPad->GetNetCode() ); + + drcItem->SetErrorMessage( msg ); + drcItem->SetItems( pad, aRefPad ); + drcItem->SetViolatingRule( nullptr ); // fixme: is this correct? + + ReportWithMarker( drcItem, aRefPad->GetPosition() ); continue; + } } // if either pad has no drill and is only on technical layers, not a clearance violation