diff --git a/eeschema/class_drc_erc_item.cpp b/eeschema/class_drc_erc_item.cpp index 5b013e7858..25b3efa498 100644 --- a/eeschema/class_drc_erc_item.cpp +++ b/eeschema/class_drc_erc_item.cpp @@ -58,8 +58,11 @@ wxString DRC_ITEM::GetErrorText() const return wxString( _("Labels are similar (lower/upper case difference only)") ); case ERCE_SIMILAR_GLBL_LABELS: return wxString( _("Global labels are similar (lower/upper case difference only)") ); + case ERCE_DIFFERENT_UNIT_FP: + return wxString( _("Different footprint assigned in another unit of the same component") ); default: + wxFAIL_MSG( "Missing ERC error description" ); return wxString( wxT("Unkown.") ); } } diff --git a/eeschema/dialogs/dialog_erc.cpp b/eeschema/dialogs/dialog_erc.cpp index 47c9d686b9..76ad135233 100644 --- a/eeschema/dialogs/dialog_erc.cpp +++ b/eeschema/dialogs/dialog_erc.cpp @@ -483,6 +483,10 @@ void DIALOG_ERC::TestErc( wxArrayString* aMessagesList ) */ TestDuplicateSheetNames( true ); + /* Test is all units of each multiunit component have the same footprint assigned. + */ + TestMultiunitFootprints( sheets ); + std::unique_ptr objectsConnectedList( m_parent->BuildNetListBase() ); // Reset the connection type indicator diff --git a/eeschema/erc.cpp b/eeschema/erc.cpp index 260bc0fa7c..13aa973204 100644 --- a/eeschema/erc.cpp +++ b/eeschema/erc.cpp @@ -38,8 +38,8 @@ #include #include #include -#include #include +#include #include @@ -225,6 +225,72 @@ int TestDuplicateSheetNames( bool aCreateMarker ) } +int TestMultiunitFootprints( SCH_SHEET_LIST& aSheetList ) +{ + int errors = 0; + std::map footprints; + SCH_MULTI_UNIT_REFERENCE_MAP refMap; + aSheetList.GetMultiUnitComponents( refMap, true ); + + for( auto& component : refMap ) + { + auto& refList = component.second; + + if( refList.GetCount() == 0 ) + { + wxFAIL; // it should not happen + continue; + } + + // Reference footprint + wxString fp; + wxString unitName; + + for( int i = 0; i < component.second.GetCount(); ++i ) + { + SCH_COMPONENT* cmp = refList.GetItem( i ).GetComp(); + SCH_SHEET_PATH sheetPath = refList.GetItem( i ).GetSheetPath(); + fp = cmp->GetField( FOOTPRINT )->GetText(); + + if( !fp.IsEmpty() ) + { + unitName = cmp->GetRef( &sheetPath ) + + LIB_PART::SubReference( cmp->GetUnit(), false ); + break; + } + } + + for( int i = 0; i < component.second.GetCount(); ++i ) + { + SCH_REFERENCE& ref = refList.GetItem( i ); + SCH_COMPONENT* unit = ref.GetComp(); + SCH_SHEET_PATH sheetPath = refList.GetItem( i ).GetSheetPath(); + const wxString& curFp = unit->GetField( FOOTPRINT )->GetText(); + + if( !curFp.IsEmpty() && fp != curFp ) + { + wxString curUnitName = unit->GetRef( &sheetPath ) + + LIB_PART::SubReference( unit->GetUnit(), false ); + + SCH_MARKER* marker = new SCH_MARKER(); + marker->SetTimeStamp( GetNewTimeStamp() ); + marker->SetData( ERCE_DIFFERENT_UNIT_FP, unit->GetPosition(), + wxString::Format( _( "Unit %s has '%s' assigned, " + "whereas unit %s has '%s' assigned" ), unitName, fp, curUnitName, curFp ), + unit->GetPosition() ); + marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); + marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING ); + ref.GetSheetPath().LastScreen()->Append( marker ); + + ++errors; + } + } + } + + return errors; +} + + void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst, int aMinConn, int aDiag ) { diff --git a/eeschema/erc.h b/eeschema/erc.h index 76cec12b98..a50fa43273 100644 --- a/eeschema/erc.h +++ b/eeschema/erc.h @@ -31,9 +31,9 @@ #define _ERC_H -//class EDA_DRAW_PANEL; class NETLIST_OBJECT; class NETLIST_OBJECT_LIST; +class SCH_SHEET_LIST; /* For ERC markers: error types (used in diags, and to set the color): */ @@ -60,6 +60,8 @@ extern const wxString CommentERC_V[]; #define ERCE_GLOBLABEL 8 // global label not connected to any other global label #define ERCE_SIMILAR_LABELS 9 // 2 labels are equal fir case insensitive comparisons #define ERCE_SIMILAR_GLBL_LABELS 10 // 2 labels are equal fir case insensitive comparisons +#define ERCE_DIFFERENT_UNIT_FP 11 // different units of the same component have different + // footprints assigned /* Minimal connection table */ #define NPI 4 // Net with Pin isolated, this pin has type Not Connected and must be left N.C. @@ -108,5 +110,12 @@ void TestOthersItems( NETLIST_OBJECT_LIST* aList, */ int TestDuplicateSheetNames( bool aCreateMarker ); +/** + * Test if all units of each multiunit component have the same footprint assigned. + * @param aSheetList contains components to be validated. + * @return The error count. + */ +int TestMultiunitFootprints( SCH_SHEET_LIST& aSheetList ); + #endif // _ERC_H