Move pin table checks to new connectivity system
This commit is contained in:
parent
a52e3fc87a
commit
48d7c46a53
|
@ -2421,7 +2421,11 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph
|
|||
{
|
||||
for( SCH_PIN* testPin : pins )
|
||||
{
|
||||
if( testPin->ConnectedItems( sheet ).empty() )
|
||||
// We only apply this test to power symbols, because other symbols have invisible
|
||||
// pins that are meant to be dangling, but the KiCad standard library power symbols
|
||||
// have invisible pins that are *not* meant to be dangling.
|
||||
if( testPin->GetLibPin()->GetParent()->IsPower() &&
|
||||
testPin->ConnectedItems( sheet ).empty() )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_PIN_NOT_CONNECTED );
|
||||
ercItem->SetItems( testPin );
|
||||
|
|
|
@ -272,90 +272,14 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||
// Reset the connection type indicator
|
||||
objectsConnectedList->ResetConnectionsType();
|
||||
|
||||
unsigned lastItemIdx = 0;
|
||||
unsigned nextItemIdx = 0;
|
||||
int MinConn = NOC;
|
||||
aReporter.ReportTail( _( "Checking pins...\n" ), RPT_SEVERITY_INFO );
|
||||
|
||||
// Check that a pin appears in only one net. This check is necessary because multi-unit
|
||||
// components that have shared pins could be wired to different nets.
|
||||
std::unordered_map<wxString, wxString> pin_to_net_map;
|
||||
if( settings.IsTestEnabled( ERCE_DIFFERENT_UNIT_NET ) )
|
||||
tester.TestMultUnitPinConflicts();
|
||||
|
||||
// The netlist generated by SCH_EDIT_FRAME::BuildNetListBase is sorted by net number, which
|
||||
// means we can group netlist items into ranges that live in the same net. The range from
|
||||
// nextItem to the current item (exclusive) needs to be checked against the current item.
|
||||
// The lastItem variable is used as a helper to pass the last item's number from one loop
|
||||
// iteration to the next, which simplifies the initial pass.
|
||||
aReporter.ReportTail( _( "Checking connections...\n" ), RPT_SEVERITY_INFO );
|
||||
for( unsigned itemIdx = 0; itemIdx < objectsConnectedList->size(); itemIdx++ )
|
||||
{
|
||||
auto item = objectsConnectedList->GetItem( itemIdx );
|
||||
auto lastItem = objectsConnectedList->GetItem( lastItemIdx );
|
||||
|
||||
auto lastNet = lastItem->GetNet();
|
||||
auto net = item->GetNet();
|
||||
|
||||
wxASSERT_MSG( lastNet <= net, wxT( "Netlist not correctly ordered" ) );
|
||||
|
||||
if( lastNet != net )
|
||||
{
|
||||
// New net found:
|
||||
MinConn = NOC;
|
||||
nextItemIdx = itemIdx;
|
||||
}
|
||||
|
||||
switch( item->m_Type )
|
||||
{
|
||||
// These items do not create erc problems
|
||||
case NETLIST_ITEM::ITEM_UNSPECIFIED:
|
||||
case NETLIST_ITEM::SEGMENT:
|
||||
case NETLIST_ITEM::BUS:
|
||||
case NETLIST_ITEM::JUNCTION:
|
||||
case NETLIST_ITEM::LABEL:
|
||||
case NETLIST_ITEM::BUSLABELMEMBER:
|
||||
case NETLIST_ITEM::PINLABEL:
|
||||
case NETLIST_ITEM::GLOBBUSLABELMEMBER:
|
||||
break;
|
||||
|
||||
// TODO(JE) Port this to the new system
|
||||
case NETLIST_ITEM::PIN:
|
||||
{
|
||||
// Check if this pin has appeared before on a different net
|
||||
if( item->m_Link && settings.IsTestEnabled( ERCE_DIFFERENT_UNIT_NET ) )
|
||||
{
|
||||
wxString ref = item->GetComponentParent()->GetRef( &item->m_SheetPath );
|
||||
wxString pin_name = ref + "_" + item->m_PinNum;
|
||||
wxString msg;
|
||||
|
||||
if( pin_to_net_map.count( pin_name ) == 0 )
|
||||
{
|
||||
pin_to_net_map[pin_name] = item->GetNetName();
|
||||
}
|
||||
else if( pin_to_net_map[pin_name] != item->GetNetName() )
|
||||
{
|
||||
msg.Printf( _( "Pin %s is connected to both %s and %s" ),
|
||||
item->m_PinNum,
|
||||
pin_to_net_map[pin_name],
|
||||
item->GetNetName() );
|
||||
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_DIFFERENT_UNIT_NET );
|
||||
ercItem->SetErrorMessage( msg );
|
||||
ercItem->SetItems( item->m_Comp );
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, item->m_Start );
|
||||
item->m_SheetPath.LastScreen()->Append( marker );
|
||||
}
|
||||
}
|
||||
|
||||
// Look for ERC problems between pins:
|
||||
tester.TestOthersItems( objectsConnectedList.get(), itemIdx, nextItemIdx, &MinConn );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
lastItemIdx = itemIdx;
|
||||
}
|
||||
// Test pins on each net against the pin connection table
|
||||
if( settings.IsTestEnabled( ERCE_PIN_TO_PIN_ERROR ) )
|
||||
tester.TestPinToPin();
|
||||
|
||||
// Test similar labels (i;e. labels which are identical when
|
||||
// using case insensitive comparisons)
|
||||
|
@ -604,7 +528,7 @@ void DIALOG_ERC::deleteAllMarkers( bool aIncludeExclusions )
|
|||
// Clear current selection list to avoid selection of deleted items
|
||||
m_parent->GetToolManager()->RunAction( EE_ACTIONS::clearSelection, true );
|
||||
|
||||
m_markerTreeModel->DeleteItems( false, true, aIncludeExclusions );
|
||||
m_markerTreeModel->DeleteItems( false, aIncludeExclusions, true );
|
||||
}
|
||||
|
||||
|
||||
|
|
143
eeschema/erc.cpp
143
eeschema/erc.cpp
|
@ -28,19 +28,20 @@
|
|||
* @brief Electrical Rules Check implementation.
|
||||
*/
|
||||
|
||||
#include "connection_graph.h"
|
||||
#include <erc.h>
|
||||
#include <fctsys.h>
|
||||
#include <kicad_string.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <netlist_object.h>
|
||||
#include <lib_pin.h>
|
||||
#include <erc.h>
|
||||
#include <netlist_object.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <sch_marker.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <sch_reference_list.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <schematic.h>
|
||||
#include <wx/ffile.h>
|
||||
#include <ws_draw_item.h>
|
||||
#include <ws_proxy_view_item.h>
|
||||
#include <wx/ffile.h>
|
||||
|
||||
|
||||
/* ERC tests :
|
||||
|
@ -580,6 +581,138 @@ int ERC_TESTER::TestNoConnectPins()
|
|||
}
|
||||
|
||||
|
||||
int ERC_TESTER::TestPinToPin()
|
||||
{
|
||||
ERC_SETTINGS& settings = m_schematic->ErcSettings();
|
||||
const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
|
||||
|
||||
int errors = 0;
|
||||
|
||||
for( const std::pair<NET_NAME_CODE, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
|
||||
{
|
||||
std::vector<SCH_PIN*> pins;
|
||||
std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
|
||||
|
||||
for( CONNECTION_SUBGRAPH* subgraph: net.second )
|
||||
{
|
||||
for( EDA_ITEM* item : subgraph->m_items )
|
||||
{
|
||||
if( item->Type() == SCH_PIN_T )
|
||||
{
|
||||
pins.emplace_back( static_cast<SCH_PIN*>( item ) );
|
||||
pinToScreenMap[item] = subgraph->m_sheet.LastScreen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Single-pin nets are handled elsewhere
|
||||
if( pins.size() < 2 )
|
||||
continue;
|
||||
|
||||
std::set<std::pair<SCH_PIN*, SCH_PIN*>> tested;
|
||||
|
||||
for( SCH_PIN* refPin : pins )
|
||||
{
|
||||
ELECTRICAL_PINTYPE refType = refPin->GetType();
|
||||
|
||||
for( SCH_PIN* testPin : pins )
|
||||
{
|
||||
if( testPin == refPin )
|
||||
continue;
|
||||
|
||||
std::pair<SCH_PIN*, SCH_PIN*> pair1 = std::make_pair( refPin, testPin );
|
||||
std::pair<SCH_PIN*, SCH_PIN*> pair2 = std::make_pair( testPin, refPin );
|
||||
|
||||
if( tested.count( pair1 ) || tested.count( pair2 ) )
|
||||
continue;
|
||||
|
||||
tested.insert( pair1 );
|
||||
tested.insert( pair2 );
|
||||
|
||||
ELECTRICAL_PINTYPE testType = testPin->GetType();
|
||||
|
||||
PIN_ERROR erc = settings.GetPinMapValue( refType, testType );
|
||||
|
||||
if( erc != PIN_ERROR::OK )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem =
|
||||
ERC_ITEM::Create( erc == PIN_ERROR::WARNING ? ERCE_PIN_TO_PIN_WARNING :
|
||||
ERCE_PIN_TO_PIN_ERROR );
|
||||
ercItem->SetItems( refPin, testPin );
|
||||
|
||||
ercItem->SetErrorMessage(
|
||||
wxString::Format( _( "Pins of type %s and %s are connected" ),
|
||||
ElectricalPinTypeGetText( refType ),
|
||||
ElectricalPinTypeGetText( testType ) ) );
|
||||
|
||||
SCH_MARKER* marker =
|
||||
new SCH_MARKER( ercItem, refPin->GetTransformedPosition() );
|
||||
pinToScreenMap[refPin]->Append( marker );
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
int ERC_TESTER::TestMultUnitPinConflicts()
|
||||
{
|
||||
const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
|
||||
|
||||
int errors = 0;
|
||||
|
||||
std::unordered_map<wxString, std::pair<wxString, SCH_PIN*>> pinToNetMap;
|
||||
|
||||
for( const std::pair<NET_NAME_CODE, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
|
||||
{
|
||||
const wxString& netName = net.first.first;
|
||||
std::vector<SCH_PIN*> pins;
|
||||
|
||||
for( CONNECTION_SUBGRAPH* subgraph : net.second )
|
||||
{
|
||||
for( EDA_ITEM* item : subgraph->m_items )
|
||||
{
|
||||
if( item->Type() == SCH_PIN_T )
|
||||
{
|
||||
SCH_PIN* pin = static_cast<SCH_PIN*>( item );
|
||||
|
||||
if( !pin->GetLibPin()->GetParent()->IsMulti() )
|
||||
continue;
|
||||
|
||||
wxString name = ( pin->GetParentComponent()->GetRef( &subgraph->m_sheet ) +
|
||||
":" + pin->GetName() );
|
||||
|
||||
if( !pinToNetMap.count( name ) )
|
||||
{
|
||||
pinToNetMap[name] = std::make_pair( netName, pin );
|
||||
}
|
||||
else if( pinToNetMap[name].first != netName )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem =
|
||||
ERC_ITEM::Create( ERCE_DIFFERENT_UNIT_NET );
|
||||
|
||||
ercItem->SetErrorMessage( wxString::Format(
|
||||
_( "Pin %s is connected to both %s and %s" ),
|
||||
pin->GetNumber(), netName, pinToNetMap[name].first ) );
|
||||
|
||||
ercItem->SetItems( pin, pinToNetMap[name].second );
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem,
|
||||
pin->GetTransformedPosition() );
|
||||
subgraph->m_sheet.LastScreen()->Append( marker );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
// this code try to detect similar labels, i.e. labels which are identical
|
||||
// when they are compared using case insensitive coparisons.
|
||||
|
||||
|
|
|
@ -106,6 +106,18 @@ public:
|
|||
*/
|
||||
int TestNoConnectPins();
|
||||
|
||||
/**
|
||||
* Checks the full netlist against the pin-to-pin connectivity requirements
|
||||
* @return the error count
|
||||
*/
|
||||
int TestPinToPin();
|
||||
|
||||
/**
|
||||
* Checks if shared pins on multi-unit components have been connected to different nets
|
||||
* @return the error count
|
||||
*/
|
||||
int TestMultUnitPinConflicts();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Performs ERC testing and creates an ERC marker to show the ERC problem for aNetItemRef
|
||||
|
|
|
@ -114,7 +114,7 @@ public:
|
|||
|
||||
bool IsTestEnabled( int aErrorCode ) const
|
||||
{
|
||||
return m_Severities.at( aErrorCode ) != RPT_SEVERITY_IGNORE;
|
||||
return GetSeverity( aErrorCode ) != RPT_SEVERITY_IGNORE;
|
||||
}
|
||||
|
||||
int GetSeverity( int aErrorCode ) const;
|
||||
|
|
Loading…
Reference in New Issue