Persist ERC pin table in project settings

Fixes https://gitlab.com/kicad/code/kicad/-/issues/2066

Also a partial fix for https://gitlab.com/kicad/code/kicad/-/issues/4577
This commit is contained in:
Jon Evans 2020-07-03 17:08:17 -04:00
parent cf38d382c7
commit b94e29e3b1
11 changed files with 344 additions and 228 deletions

View File

@ -196,19 +196,20 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
SCH_SCREENS screens( sch->Root() ); SCH_SCREENS screens( sch->Root() );
ERC_SETTINGS& settings = sch->ErcSettings(); ERC_SETTINGS& settings = sch->ErcSettings();
ERC_TESTER tester( sch );
// Test duplicate sheet names inside a given sheet. While one can have multiple references // Test duplicate sheet names inside a given sheet. While one can have multiple references
// to the same file, each must have a unique name. // to the same file, each must have a unique name.
if( settings.IsTestEnabled( ERCE_DUPLICATE_SHEET_NAME ) ) if( settings.IsTestEnabled( ERCE_DUPLICATE_SHEET_NAME ) )
{ {
aReporter.ReportTail( _( "Checking sheet names...\n" ), RPT_SEVERITY_INFO ); aReporter.ReportTail( _( "Checking sheet names...\n" ), RPT_SEVERITY_INFO );
TestDuplicateSheetNames( sch, true ); tester.TestDuplicateSheetNames( true );
} }
if( settings.IsTestEnabled( ERCE_BUS_ALIAS_CONFLICT ) ) if( settings.IsTestEnabled( ERCE_BUS_ALIAS_CONFLICT ) )
{ {
aReporter.ReportTail( _( "Checking bus conflicts...\n" ), RPT_SEVERITY_INFO ); aReporter.ReportTail( _( "Checking bus conflicts...\n" ), RPT_SEVERITY_INFO );
TestConflictingBusAliases( sch ); tester.TestConflictingBusAliases();
} }
// The connection graph has a whole set of ERC checks it can run // The connection graph has a whole set of ERC checks it can run
@ -220,8 +221,8 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
if( settings.IsTestEnabled( ERCE_DIFFERENT_UNIT_FP ) ) if( settings.IsTestEnabled( ERCE_DIFFERENT_UNIT_FP ) )
{ {
aReporter.ReportTail( _( "Checking footprints...\n" ), RPT_SEVERITY_INFO ); aReporter.ReportTail( _( "Checking footprints...\n" ), RPT_SEVERITY_INFO );
SCH_SHEET_LIST sheets = sch->GetSheets();
TestMultiunitFootprints( sheets ); tester.TestMultiunitFootprints();
} }
std::unique_ptr<NETLIST_OBJECT_LIST> objectsConnectedList( m_parent->BuildNetListBase() ); std::unique_ptr<NETLIST_OBJECT_LIST> objectsConnectedList( m_parent->BuildNetListBase() );
@ -304,7 +305,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
} }
// Look for ERC problems between pins: // Look for ERC problems between pins:
TestOthersItems( objectsConnectedList.get(), itemIdx, nextItemIdx, &MinConn ); tester.TestOthersItems( objectsConnectedList.get(), itemIdx, nextItemIdx, &MinConn );
break; break;
} }
default: default:
@ -323,7 +324,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
} }
if( settings.IsTestEnabled( ERCE_UNRESOLVED_VARIABLE ) ) if( settings.IsTestEnabled( ERCE_UNRESOLVED_VARIABLE ) )
TestTextVars( sch, m_parent->GetCanvas()->GetView()->GetWorksheet() ); tester.TestTextVars( m_parent->GetCanvas()->GetView()->GetWorksheet() );
// Display diags: // Display diags:
m_markerTreeModel->SetProvider( m_markerProvider ); m_markerTreeModel->SetProvider( m_markerProvider );

View File

@ -33,6 +33,7 @@
#include <netlist_object.h> #include <netlist_object.h>
#include <lib_pin.h> #include <lib_pin.h>
#include <sch_component.h> #include <sch_component.h>
#include <schematic.h>
#include <connection_graph.h> #include <connection_graph.h>
#include <tools/ee_actions.h> #include <tools/ee_actions.h>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
@ -41,11 +42,6 @@
#include <id.h> #include <id.h>
#include <widgets/wx_angle_text.h> #include <widgets/wx_angle_text.h>
extern int PinMap[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL];
extern int DefaultPinMap[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL];
bool PANEL_SETUP_PINMAP::m_diagErcTableInit = false; // saved only for the current session
// Control identifiers for events // Control identifiers for events
#define ID_MATRIX_0 1800 #define ID_MATRIX_0 1800
@ -63,7 +59,8 @@ PANEL_SETUP_PINMAP::PANEL_SETUP_PINMAP( wxWindow* aWindow, SCH_EDIT_FRAME* paren
m_buttonList(), m_buttonList(),
m_initialized( false ) m_initialized( false )
{ {
m_parent = parent; m_parent = parent;
m_schematic = &parent->Schematic();
wxFont infoFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ); wxFont infoFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
infoFont.SetSymbolicSize( wxFONTSIZE_SMALL ); infoFont.SetSymbolicSize( wxFONTSIZE_SMALL );
@ -74,7 +71,7 @@ PANEL_SETUP_PINMAP::PANEL_SETUP_PINMAP( wxWindow* aWindow, SCH_EDIT_FRAME* paren
void PANEL_SETUP_PINMAP::OnResetMatrixClick( wxCommandEvent& aEvent ) void PANEL_SETUP_PINMAP::OnResetMatrixClick( wxCommandEvent& aEvent )
{ {
memcpy( PinMap, DefaultPinMap, sizeof( PinMap ) ); m_schematic->ErcSettings().ResetPinMap();
ReBuildMatrixPanel(); ReBuildMatrixPanel();
} }
@ -86,12 +83,6 @@ void PANEL_SETUP_PINMAP::ReBuildMatrixPanel()
wxSize bitmap_size = dummy->GetSize(); wxSize bitmap_size = dummy->GetSize();
delete dummy; delete dummy;
if( !m_diagErcTableInit )
{
memcpy( PinMap, DefaultPinMap, sizeof(DefaultPinMap) );
m_diagErcTableInit = true;
}
wxPoint pos; wxPoint pos;
// Get the current text size using a dummy text. // Get the current text size using a dummy text.
wxStaticText* text = new wxStaticText( m_matrixPanel, -1, CommentERC_V[0], pos ); wxStaticText* text = new wxStaticText( m_matrixPanel, -1, CommentERC_V[0], pos );
@ -140,16 +131,16 @@ void PANEL_SETUP_PINMAP::ReBuildMatrixPanel()
for( int jj = 0; jj <= ii; jj++ ) for( int jj = 0; jj <= ii; jj++ )
{ {
// Add column labels (only once) // Add column labels (only once)
int diag = PinMap[ii][jj]; PIN_ERROR diag = m_schematic->ErcSettings().GetPinMapValue( ii, jj );
int x = pos.x + ( jj * ( bitmap_size.x + 4 ) );
if( (ii == jj) && !m_initialized ) int x = pos.x + ( jj * ( bitmap_size.x + 4 ) );
if( ( ii == jj ) && !m_initialized )
{ {
wxPoint txtpos; wxPoint txtpos;
txtpos.x = x + (bitmap_size.x / 2); txtpos.x = x + ( bitmap_size.x / 2 );
txtpos.y = y - text_height; txtpos.y = y - text_height;
new WX_ANGLE_TEXT( m_matrixPanel, wxID_ANY, CommentERC_V[ii], new WX_ANGLE_TEXT( m_matrixPanel, wxID_ANY, CommentERC_V[ii], txtpos, 450 );
txtpos, 450 );
} }
int event_id = ID_MATRIX_0 + ii + ( jj * ELECTRICAL_PINTYPES_TOTAL ); int event_id = ID_MATRIX_0 + ii + ( jj * ELECTRICAL_PINTYPES_TOTAL );
@ -189,24 +180,24 @@ bool PANEL_SETUP_PINMAP::Show( bool show )
} }
void PANEL_SETUP_PINMAP::setDRCMatrixButtonState( wxBitmapButton *aButton, int aState ) void PANEL_SETUP_PINMAP::setDRCMatrixButtonState( wxBitmapButton *aButton, PIN_ERROR aState )
{ {
BITMAP_DEF bitmap_butt = nullptr; BITMAP_DEF bitmap_butt = nullptr;
wxString tooltip; wxString tooltip;
switch( aState ) switch( aState )
{ {
case OK: case PIN_ERROR::OK:
bitmap_butt = erc_green_xpm; bitmap_butt = erc_green_xpm;
tooltip = _( "No error or warning" ); tooltip = _( "No error or warning" );
break; break;
case WAR: case PIN_ERROR::WARNING:
bitmap_butt = ercwarn_xpm; bitmap_butt = ercwarn_xpm;
tooltip = _( "Generate warning" ); tooltip = _( "Generate warning" );
break; break;
case ERR: case PIN_ERROR::ERROR:
bitmap_butt = ercerr_xpm; bitmap_butt = ercerr_xpm;
tooltip = _( "Generate error" ); tooltip = _( "Generate error" );
break; break;
@ -231,11 +222,13 @@ void PANEL_SETUP_PINMAP::ChangeErrorLevel( wxCommandEvent& event )
int y = ii % ELECTRICAL_PINTYPES_TOTAL; int y = ii % ELECTRICAL_PINTYPES_TOTAL;
wxBitmapButton* butt = (wxBitmapButton*) event.GetEventObject(); wxBitmapButton* butt = (wxBitmapButton*) event.GetEventObject();
int level = ( PinMap[y][x] + 1 ) % 3; int level = static_cast<int>( m_schematic->ErcSettings().GetPinMapValue( y, x ) );
level = ( level + 1 ) % 3;
setDRCMatrixButtonState( butt, level ); setDRCMatrixButtonState( butt, static_cast<PIN_ERROR>( level ) );
PinMap[y][x] = PinMap[x][y] = level; m_schematic->ErcSettings().SetPinMapValue( y, x, static_cast<PIN_ERROR>( level ) );
m_schematic->ErcSettings().SetPinMapValue( x, y, static_cast<PIN_ERROR>( level ) );
} }

View File

@ -32,6 +32,7 @@
class SCH_EDIT_FRAME; class SCH_EDIT_FRAME;
class SCHEMATIC;
class PANEL_SETUP_PINMAP : public PANEL_SETUP_PINMAP_BASE class PANEL_SETUP_PINMAP : public PANEL_SETUP_PINMAP_BASE
@ -40,6 +41,7 @@ class PANEL_SETUP_PINMAP : public PANEL_SETUP_PINMAP_BASE
private: private:
SCH_EDIT_FRAME* m_parent; SCH_EDIT_FRAME* m_parent;
SCHEMATIC* m_schematic;
wxBitmapButton* m_buttonList[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL]; wxBitmapButton* m_buttonList[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL];
bool m_initialized; bool m_initialized;
static bool m_diagErcTableInit; // go to true after DiagErc init static bool m_diagErcTableInit; // go to true after DiagErc init
@ -54,7 +56,7 @@ private:
void ChangeErrorLevel( wxCommandEvent& event ); void ChangeErrorLevel( wxCommandEvent& event );
void ReBuildMatrixPanel(); void ReBuildMatrixPanel();
void setDRCMatrixButtonState( wxBitmapButton *aButton, int aState ); void setDRCMatrixButtonState( wxBitmapButton *aButton, PIN_ERROR aState );
}; };

View File

@ -98,72 +98,14 @@ const wxString CommentERC_V[] =
}; };
/* Look up table which gives the diag for a pair of connected pins int ERC_TESTER::TestDuplicateSheetNames( bool aCreateMarker )
* Can be modified by ERC options.
* at start up: must be loaded by DefaultDiagErc
* Can be modified in dialog ERC
*/
int PinMap[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL];
/**
* Default Look up table which gives the ERC error level for a pair of connected pins
* Same as DiagErc, but cannot be modified.
* Used to init or reset DiagErc
* note also, to avoid inconsistancy:
* DefaultDiagErc[i][j] = DefaultDiagErc[j][i]
*/
int DefaultPinMap[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL] =
{
/* I, O, Bi, 3S, Pas, UnS, PwrI, PwrO, OC, OE, NC */
/* I */ { OK, OK, OK, OK, OK, WAR, OK, OK, OK, OK, ERR },
/* O */ { OK, ERR, OK, WAR, OK, WAR, OK, ERR, ERR, ERR, ERR },
/* Bi*/ { OK, OK, OK, OK, OK, WAR, OK, WAR, OK, WAR, ERR },
/* 3S*/ { OK, WAR, OK, OK, OK, WAR, WAR, ERR, WAR, WAR, ERR },
/*Pas*/ { OK, OK, OK, OK, OK, WAR, OK, OK, OK, OK, ERR },
/*UnS */ { WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, ERR },
/*PwrI*/ { OK, OK, OK, WAR, OK, WAR, OK, OK, OK, OK, ERR },
/*PwrO*/ { OK, ERR, WAR, ERR, OK, WAR, OK, ERR, ERR, ERR, ERR },
/* OC */ { OK, ERR, OK, WAR, OK, WAR, OK, ERR, OK, OK, ERR },
/* OE */ { OK, ERR, WAR, WAR, OK, WAR, OK, ERR, OK, OK, ERR },
/* NC */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR }
};
/**
* Look up table which gives the minimal drive for a pair of connected pins on
* a net.
* <p>
* The initial state of a net is NOC (Net with No Connection). It can be updated to
* NPI (Pin Isolated), NET_NC (Net with a no connect symbol), NOD (Not Driven) or DRV
* (DRIven). It can be updated to NET_NC with no error only if there is only one pin
* in net. Nets are OK when their final state is NET_NC or DRV. Nets with the state
* NOD have no valid source signal.
*/
static int MinimalReq[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL] =
{
/* In Out, Bi, 3S, Pas, UnS, PwrI,PwrO,OC, OE, NC */
/* In*/ { NOD, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
/*Out*/ { DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, NPI },
/* Bi*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
/* 3S*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
/*Pas*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
/*UnS*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
/*PwrI*/ { NOD, DRV, NOD, NOD, NOD, NOD, NOD, DRV, NOD, NOD, NPI },
/*PwrO*/ { DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, NPI },
/* OC*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
/* OE*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
/* NC*/ { NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI }
};
int TestDuplicateSheetNames( SCHEMATIC* aSchematic, bool aCreateMarker )
{ {
SCH_SCREEN* screen; SCH_SCREEN* screen;
int err_count = 0; int err_count = 0;
SCH_SCREENS screenList( aSchematic->Root() ); SCH_SCREENS screenList( m_schematic->Root() );
for( screen = screenList.GetFirst(); screen != NULL; screen = screenList.GetNext() ) for( screen = screenList.GetFirst(); screen != nullptr; screen = screenList.GetNext() )
{ {
std::vector<SCH_SHEET*> list; std::vector<SCH_SHEET*> list;
@ -202,7 +144,7 @@ int TestDuplicateSheetNames( SCHEMATIC* aSchematic, bool aCreateMarker )
} }
void TestTextVars( SCHEMATIC* aSchematic, KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet ) void ERC_TESTER::TestTextVars( KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet )
{ {
WS_DRAW_ITEM_LIST wsItems; WS_DRAW_ITEM_LIST wsItems;
@ -212,7 +154,7 @@ void TestTextVars( SCHEMATIC* aSchematic, KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet
wsItems.BuildWorkSheetGraphicList( aWorksheet->GetPageInfo(), aWorksheet->GetTitleBlock() ); wsItems.BuildWorkSheetGraphicList( aWorksheet->GetPageInfo(), aWorksheet->GetTitleBlock() );
} }
SCH_SCREENS screens( aSchematic->Root() ); SCH_SCREENS screens( m_schematic->Root() );
for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() )
{ {
@ -297,12 +239,12 @@ void TestTextVars( SCHEMATIC* aSchematic, KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet
} }
int TestConflictingBusAliases( SCHEMATIC* aSchematic ) int ERC_TESTER::TestConflictingBusAliases()
{ {
wxString msg; wxString msg;
int err_count = 0; int err_count = 0;
SCH_SCREENS screens( aSchematic->Root() ); SCH_SCREENS screens( m_schematic->Root() );
std::vector< std::shared_ptr<BUS_ALIAS> > aliases; std::vector< std::shared_ptr<BUS_ALIAS> > aliases;
for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() )
@ -338,12 +280,14 @@ int TestConflictingBusAliases( SCHEMATIC* aSchematic )
} }
int TestMultiunitFootprints( const SCH_SHEET_LIST& aSheetList ) int ERC_TESTER::TestMultiunitFootprints()
{ {
SCH_SHEET_LIST sheets = m_schematic->GetSheets();
int errors = 0; int errors = 0;
std::map<wxString, LIB_ID> footprints; std::map<wxString, LIB_ID> footprints;
SCH_MULTI_UNIT_REFERENCE_MAP refMap; SCH_MULTI_UNIT_REFERENCE_MAP refMap;
aSheetList.GetMultiUnitComponents( refMap, true ); sheets.GetMultiUnitComponents( refMap, true );
for( auto& component : refMap ) for( auto& component : refMap )
{ {
@ -402,9 +346,10 @@ int TestMultiunitFootprints( const SCH_SHEET_LIST& aSheetList )
} }
void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst, int aMinConn, int aDiag ) void ERC_TESTER::diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst, int aMinConn,
PIN_ERROR aDiag )
{ {
if( aDiag == OK || aMinConn < 1 || aNetItemRef->m_Type != NETLIST_ITEM::PIN ) if( aDiag == PIN_ERROR::OK || aMinConn < 1 || aNetItemRef->m_Type != NETLIST_ITEM::PIN )
return; return;
SCH_PIN* pin = static_cast<SCH_PIN*>( aNetItemRef->m_Comp ); SCH_PIN* pin = static_cast<SCH_PIN*>( aNetItemRef->m_Comp );
@ -424,8 +369,8 @@ void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst, int aMi
if( aNetItemTst && aNetItemTst->m_Type == NETLIST_ITEM::PIN ) /* Error between 2 pins */ if( aNetItemTst && aNetItemTst->m_Type == NETLIST_ITEM::PIN ) /* Error between 2 pins */
{ {
ERC_ITEM* ercItem = ERC_ITEM::Create( aDiag == ERR ? ERCE_PIN_TO_PIN_ERROR ERC_ITEM* ercItem = ERC_ITEM::Create( aDiag == PIN_ERROR::ERROR ?
: ERCE_PIN_TO_PIN_WARNING ); ERCE_PIN_TO_PIN_ERROR : ERCE_PIN_TO_PIN_WARNING );
ercItem->SetItems( pin, static_cast<SCH_PIN*>( aNetItemTst->m_Comp ) ); ercItem->SetItems( pin, static_cast<SCH_PIN*>( aNetItemTst->m_Comp ) );
SCH_MARKER* marker = new SCH_MARKER( ercItem, aNetItemRef->m_Start ); SCH_MARKER* marker = new SCH_MARKER( ercItem, aNetItemRef->m_Start );
@ -434,12 +379,14 @@ void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst, int aMi
} }
void TestOthersItems( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef, unsigned aNetStart, void ERC_TESTER::TestOthersItems( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef,
int* aMinConnexion ) unsigned aNetStart, int* aMinConnexion )
{ {
ERC_SETTINGS& settings = m_schematic->ErcSettings();
unsigned netItemTst = aNetStart; unsigned netItemTst = aNetStart;
ELECTRICAL_PINTYPE jj; ELECTRICAL_PINTYPE jj;
int erc = OK; PIN_ERROR erc = PIN_ERROR::OK;
/* Analysis of the table of connections. */ /* Analysis of the table of connections. */
ELECTRICAL_PINTYPE ref_elect_type = aList->GetItem( aNetItemRef )->m_ElectricalPinType; ELECTRICAL_PINTYPE ref_elect_type = aList->GetItem( aNetItemRef )->m_ElectricalPinType;
@ -457,11 +404,11 @@ void TestOthersItems( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef, unsigned
if( netItemTst < aList->size() ) if( netItemTst < aList->size() )
{ {
ELECTRICAL_PINTYPE test_elect_type = aList->GetItem( netItemTst )->m_ElectricalPinType; ELECTRICAL_PINTYPE test_elect_type = aList->GetItem( netItemTst )->m_ElectricalPinType;
erc = PinMap[static_cast<int>( ref_elect_type )][static_cast<int>(test_elect_type )]; erc = settings.GetPinMapValue( ref_elect_type, test_elect_type );
} }
if( erc != OK ) if( erc != PIN_ERROR::OK )
Diagnose( aList->GetItem( aNetItemRef ), aList->GetItem( netItemTst ), 1, erc ); diagnose( aList->GetItem( aNetItemRef ), aList->GetItem( netItemTst ), 1, erc );
// We examine only a given net. We stop the search if the net changes // We examine only a given net. We stop the search if the net changes
if( ( netItemTst >= aList->size() ) // End of list if( ( netItemTst >= aList->size() ) // End of list
@ -518,7 +465,10 @@ void TestOthersItems( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef, unsigned
} }
if( seterr ) if( seterr )
Diagnose( aList->GetItem( aNetItemRef ), NULL, local_minconn, WAR ); {
diagnose( aList->GetItem( aNetItemRef ), nullptr, local_minconn,
PIN_ERROR::WARNING );
}
*aMinConnexion = DRV; // inhibiting other messages of this *aMinConnexion = DRV; // inhibiting other messages of this
// type for the net. // type for the net.
@ -549,18 +499,17 @@ void TestOthersItems( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef, unsigned
case NETLIST_ITEM::PIN: case NETLIST_ITEM::PIN:
jj = aList->GetItem( netItemTst )->m_ElectricalPinType; jj = aList->GetItem( netItemTst )->m_ElectricalPinType;
local_minconn = std::max( local_minconn = std::max( settings.GetPinMinDrive( ref_elect_type, jj ),
MinimalReq[static_cast<int>( ref_elect_type )][static_cast<int>( jj )], local_minconn );
local_minconn );
if( netItemTst <= aNetItemRef ) if( netItemTst <= aNetItemRef )
break; break;
if( erc == OK ) if( erc == PIN_ERROR::OK )
{ {
erc = PinMap[static_cast<int>( ref_elect_type )][static_cast<int>( jj )]; erc = settings.GetPinMapValue( ref_elect_type, jj );
if( erc != OK ) if( erc != PIN_ERROR::OK )
{ {
if( aList->GetConnectionType( netItemTst ) == NET_CONNECTION::UNCONNECTED ) if( aList->GetConnectionType( netItemTst ) == NET_CONNECTION::UNCONNECTED )
{ {

View File

@ -30,6 +30,8 @@
#ifndef _ERC_H #ifndef _ERC_H
#define _ERC_H #define _ERC_H
#include <erc_settings.h>
class NETLIST_OBJECT; class NETLIST_OBJECT;
class NETLIST_OBJECT_LIST; class NETLIST_OBJECT_LIST;
@ -41,110 +43,73 @@ namespace KIGFX
class WS_PROXY_VIEW_ITEM; class WS_PROXY_VIEW_ITEM;
} }
/* For ERC markers: error types (used in diags, and to set the color):
*/
enum errortype
{
OK = 0,
WAR, // Error: severity = warning
ERR, // Error: severity = error
UNC // Error: unconnected pin
};
extern const wxString CommentERC_H[]; extern const wxString CommentERC_H[];
extern const wxString CommentERC_V[]; extern const wxString CommentERC_V[];
/// DRC error codes:
enum ERCE_T class ERC_TESTER
{ {
ERCE_UNSPECIFIED = 0, public:
ERCE_FIRST,
ERCE_DUPLICATE_SHEET_NAME = ERCE_FIRST, // duplicate sheet names within a given sheet
ERCE_PIN_NOT_CONNECTED, // pin not connected and not no connect symbol
ERCE_PIN_NOT_DRIVEN, // pin connected to some others pins but no pin to drive it
ERCE_HIERACHICAL_LABEL, // mismatch between hierarchical labels and pins sheets
ERCE_NOCONNECT_CONNECTED, // a no connect symbol is connected to more than 1 pin
ERCE_NOCONNECT_NOT_CONNECTED, // a no connect symbol is not connected to anything
ERCE_LABEL_NOT_CONNECTED, // label not connected to anything
ERCE_SIMILAR_LABELS, // 2 labels are equal fir case insensitive comparisons
ERCE_DIFFERENT_UNIT_FP, // different units of the same component have different footprints assigned
ERCE_DIFFERENT_UNIT_NET, // a shared pin in a multi-unit component is connected to more than one net
ERCE_BUS_ALIAS_CONFLICT, // conflicting bus alias definitions across sheets
ERCE_DRIVER_CONFLICT, // conflicting drivers (labels, etc) on a subgraph
ERCE_BUS_ENTRY_CONFLICT, // a wire connected to a bus doesn't match the bus
ERCE_BUS_LABEL_ERROR, // a label attached to a bus isn't in bus format
ERCE_BUS_TO_BUS_CONFLICT, // a connection between bus objects doesn't share at least one net
ERCE_BUS_TO_NET_CONFLICT, // a bus wire is graphically connected to a net port/pin (or vice versa)
ERCE_GLOBLABEL, // a global label is unique
ERCE_UNRESOLVED_VARIABLE,
ERCE_LAST = ERCE_UNRESOLVED_VARIABLE,
// Errors after this point will not automatically appear in the Severities Panel ERC_TESTER( SCHEMATIC* aSchematic ) :
m_schematic( aSchematic )
{
}
ERCE_PIN_TO_PIN_WARNING, // pin connected to an other pin: warning level /**
ERCE_PIN_TO_PIN_ERROR, // pin connected to an other pin: error level * Perform ERC testing for electrical conflicts between \a NetItemRef and other items
* (mainly pin) on the same net.
* @param aList = a reference to the list of connected objects
* @param aNetItemRef = index in list of the current object
* @param aNetStart = index in list of net objects of the first item
* @param aMinConnexion = a pointer to a variable to store the minimal connection
* found( NOD, DRV, NPI, NET_NC)
*/
void TestOthersItems( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef, unsigned aNetStart,
int* aMinConnexion );
/**
* inside a given sheet, one cannot have sheets with duplicate names (file
* names can be duplicated).
* @return the error count
* @param aCreateMarker: true = create error markers in schematic,
* false = calculate error count only
*/
int TestDuplicateSheetNames( bool aCreateMarker );
/**
* Checks for any unresolved text variable references.
*/
void TestTextVars( KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet );
/**
* Checks that there are not conflicting bus alias definitions in the schematic
*
* (for example, two hierarchical sub-sheets contain different definitions for
* the same bus alias)
*
* @return the error count
*/
int TestConflictingBusAliases();
/**
* Test if all units of each multiunit component have the same footprint assigned.
* @return The error count.
*/
int TestMultiunitFootprints();
private:
/**
* Performs ERC testing and creates an ERC marker to show the ERC problem for aNetItemRef
* or between aNetItemRef and aNetItemTst.
* if MinConn < 0: this is an error on labels
*/
void diagnose( NETLIST_OBJECT* NetItemRef, NETLIST_OBJECT* NetItemTst, int MinConnexion,
PIN_ERROR Diag );
SCHEMATIC* m_schematic;
}; };
/* Minimal connection table */
#define NPI 4 // Net with Pin isolated, this pin has type Not Connected and must be left N.C.
#define DRV 3 // Net driven by a signal (a pin output for instance)
#define NET_NC 2 // Net "connected" to a "NoConnect symbol"
#define NOD 1 // Net not driven ( Such as 2 or more connected inputs )
#define NOC 0 // initial state of a net: no connection
/**
* Performs ERC testing and creates an ERC marker to show the ERC problem for aNetItemRef
* or between aNetItemRef and aNetItemTst.
* if MinConn < 0: this is an error on labels
*/
void Diagnose( NETLIST_OBJECT* NetItemRef, NETLIST_OBJECT* NetItemTst, int MinConnexion,
int Diag );
/**
* Perform ERC testing for electrical conflicts between \a NetItemRef and other items
* (mainly pin) on the same net.
* @param aList = a reference to the list of connected objects
* @param aNetItemRef = index in list of the current object
* @param aNetStart = index in list of net objects of the first item
* @param aMinConnexion = a pointer to a variable to store the minimal connection
* found( NOD, DRV, NPI, NET_NC)
*/
void TestOthersItems( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef, unsigned aNetStart,
int* aMinConnexion );
/**
* Function TestDuplicateSheetNames( )
* inside a given sheet, one cannot have sheets with duplicate names (file
* names can be duplicated).
* @return the error count
* @param aCreateMarker: true = create error markers in schematic,
* false = calculate error count only
*/
int TestDuplicateSheetNames( SCHEMATIC* aSchematic, bool aCreateMarker );
/**
* Function TestTextVars()
* Checks for any unresolved text variable references.
*/
void TestTextVars( SCHEMATIC* aSchematic, KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet );
/**
* Checks that there are not conflicting bus alias definitions in the schematic
*
* (for example, two hierarchical sub-sheets contain different definitions for
* the same bus alias)
*
* @return the error count
*/
int TestConflictingBusAliases( SCHEMATIC* aSchematic );
/**
* 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( const SCH_SHEET_LIST& aSheetList );
#endif // _ERC_H #endif // _ERC_H

View File

@ -49,7 +49,11 @@ ERC_ITEM ERC_ITEM::pinNotDriven( ERCE_PIN_NOT_DRIVEN,
_( "Pin connected to other pins, but not driven by any pin" ), _( "Pin connected to other pins, but not driven by any pin" ),
wxT( "pin_not_driven" ) ); wxT( "pin_not_driven" ) );
ERC_ITEM ERC_ITEM::pinTableConflict( ERCE_PIN_TO_PIN_ERROR, ERC_ITEM ERC_ITEM::pinTableWarning( ERCE_PIN_TO_PIN_WARNING,
_( "Conflict problem between pins" ),
wxT( "pin_to_pin" ) );
ERC_ITEM ERC_ITEM::pinTableError( ERCE_PIN_TO_PIN_ERROR,
_( "Conflict problem between pins" ), _( "Conflict problem between pins" ),
wxT( "pin_to_pin" ) ); wxT( "pin_to_pin" ) );
@ -117,7 +121,7 @@ std::vector<std::reference_wrapper<RC_ITEM>> ERC_ITEM::allItemTypes( {
ERC_ITEM::duplicateSheetName, ERC_ITEM::duplicateSheetName,
ERC_ITEM::pinNotConnected, ERC_ITEM::pinNotConnected,
ERC_ITEM::pinNotDriven, ERC_ITEM::pinNotDriven,
ERC_ITEM::pinTableConflict, ERC_ITEM::pinTableWarning,
ERC_ITEM::hierLabelMismatch, ERC_ITEM::hierLabelMismatch,
ERC_ITEM::noConnectConnected, ERC_ITEM::noConnectConnected,
ERC_ITEM::noConnectDangling, ERC_ITEM::noConnectDangling,
@ -151,8 +155,10 @@ ERC_ITEM* ERC_ITEM::Create( int aErrorCode )
return new ERC_ITEM( pinNotDriven ); return new ERC_ITEM( pinNotDriven );
case ERCE_PIN_TO_PIN_WARNING: case ERCE_PIN_TO_PIN_WARNING:
return new ERC_ITEM( pinTableWarning );
case ERCE_PIN_TO_PIN_ERROR: case ERCE_PIN_TO_PIN_ERROR:
return new ERC_ITEM( pinTableConflict ); return new ERC_ITEM( pinTableError );
case ERCE_HIERACHICAL_LABEL: case ERCE_HIERACHICAL_LABEL:
return new ERC_ITEM( hierLabelMismatch ); return new ERC_ITEM( hierLabelMismatch );

View File

@ -55,7 +55,8 @@ private:
static ERC_ITEM duplicateSheetName; static ERC_ITEM duplicateSheetName;
static ERC_ITEM pinNotConnected; static ERC_ITEM pinNotConnected;
static ERC_ITEM pinNotDriven; static ERC_ITEM pinNotDriven;
static ERC_ITEM pinTableConflict; static ERC_ITEM pinTableWarning;
static ERC_ITEM pinTableError;
static ERC_ITEM hierLabelMismatch; static ERC_ITEM hierLabelMismatch;
static ERC_ITEM noConnectConnected; static ERC_ITEM noConnectConnected;
static ERC_ITEM noConnectDangling; static ERC_ITEM noConnectDangling;

View File

@ -29,13 +29,68 @@
const int ercSettingsSchemaVersion = 0; const int ercSettingsSchemaVersion = 0;
#define OK PIN_ERROR::OK
#define ERR PIN_ERROR::ERROR
#define WAR PIN_ERROR::WARNING
/**
* Default Look up table which gives the ERC error level for a pair of connected pins
*/
PIN_ERROR ERC_SETTINGS::m_defaultPinMap[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL] =
{
/* I, O, Bi, 3S, Pas, UnS, PwrI, PwrO, OC, OE, NC */
/* I */ { OK, OK, OK, OK, OK, WAR, OK, OK, OK, OK, ERR },
/* O */ { OK, ERR, OK, WAR, OK, WAR, OK, ERR, ERR, ERR, ERR },
/* Bi*/ { OK, OK, OK, OK, OK, WAR, OK, WAR, OK, WAR, ERR },
/* 3S*/ { OK, WAR, OK, OK, OK, WAR, WAR, ERR, WAR, WAR, ERR },
/*Pas*/ { OK, OK, OK, OK, OK, WAR, OK, OK, OK, OK, ERR },
/*UnS */ { WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, ERR },
/*PwrI*/ { OK, OK, OK, WAR, OK, WAR, OK, OK, OK, OK, ERR },
/*PwrO*/ { OK, ERR, WAR, ERR, OK, WAR, OK, ERR, ERR, ERR, ERR },
/* OC */ { OK, ERR, OK, WAR, OK, WAR, OK, ERR, OK, OK, ERR },
/* OE */ { OK, ERR, WAR, WAR, OK, WAR, OK, ERR, OK, OK, ERR },
/* NC */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR }
};
/**
* Look up table which gives the minimal drive for a pair of connected pins on
* a net.
* <p>
* The initial state of a net is NOC (Net with No Connection). It can be updated to
* NPI (Pin Isolated), NET_NC (Net with a no connect symbol), NOD (Not Driven) or DRV
* (DRIven). It can be updated to NET_NC with no error only if there is only one pin
* in net. Nets are OK when their final state is NET_NC or DRV. Nets with the state
* NOD have no valid source signal.
*/
int ERC_SETTINGS::m_PinMinDrive[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL] =
{
/* In Out, Bi, 3S, Pas, UnS, PwrI,PwrO,OC, OE, NC */
/* In*/ { NOD, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
/*Out*/ { DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, NPI },
/* Bi*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
/* 3S*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
/*Pas*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
/*UnS*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
/*PwrI*/ { NOD, DRV, NOD, NOD, NOD, NOD, NOD, DRV, NOD, NOD, NPI },
/*PwrO*/ { DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, NPI },
/* OC*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
/* OE*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
/* NC*/ { NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI }
};
ERC_SETTINGS::ERC_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) : ERC_SETTINGS::ERC_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
NESTED_SETTINGS( "erc", ercSettingsSchemaVersion, aParent, aPath ) NESTED_SETTINGS( "erc", ercSettingsSchemaVersion, aParent, aPath )
{ {
ResetPinMap();
for( int i = ERCE_FIRST; i <= ERCE_LAST; ++i ) for( int i = ERCE_FIRST; i <= ERCE_LAST; ++i )
m_Severities[ i ] = RPT_SEVERITY_ERROR; m_Severities[ i ] = RPT_SEVERITY_ERROR;
m_Severities[ ERCE_UNSPECIFIED ] = RPT_SEVERITY_UNDEFINED; m_Severities[ERCE_UNSPECIFIED] = RPT_SEVERITY_UNDEFINED;
m_Severities[ERCE_PIN_TO_PIN_WARNING] = RPT_SEVERITY_WARNING;
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "rule_severities", m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "rule_severities",
[&]() -> nlohmann::json [&]() -> nlohmann::json
@ -74,6 +129,52 @@ ERC_SETTINGS::ERC_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
} }
}, },
{} ) ); {} ) );
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "pin_map",
[&]() -> nlohmann::json
{
nlohmann::json ret = nlohmann::json::array();
for( int i = 0; i < ELECTRICAL_PINTYPES_TOTAL; i++ )
{
nlohmann::json inner = nlohmann::json::array();
for( int j = 0; j < ELECTRICAL_PINTYPES_TOTAL; j++ )
inner.push_back( static_cast<int>( GetPinMapValue( i, j ) ) );
ret.push_back( inner );
}
return ret;
},
[&]( const nlohmann::json& aJson )
{
if( !aJson.is_array() || aJson.size() != ELECTRICAL_PINTYPES_TOTAL )
return;
for( size_t i = 0; i < ELECTRICAL_PINTYPES_TOTAL; i++ )
{
if( i > aJson.size() - 1 )
break;
nlohmann::json inner = aJson[i];
if( !inner.is_array() || inner.size() != ELECTRICAL_PINTYPES_TOTAL )
return;
for( size_t j = 0; j < ELECTRICAL_PINTYPES_TOTAL; j++ )
{
if( inner[j].is_number_integer() )
{
int val = inner[j].get<int>();
if( val >= 0 && val <= static_cast<int>( PIN_ERROR::UNCONNECTED ) )
SetPinMapValue( i, j, static_cast<PIN_ERROR>( val ) );
}
}
}
},
{} ) );
} }
@ -89,9 +190,6 @@ ERC_SETTINGS::~ERC_SETTINGS()
int ERC_SETTINGS::GetSeverity( int aErrorCode ) const int ERC_SETTINGS::GetSeverity( int aErrorCode ) const
{ {
wxCHECK_MSG( m_Severities.count( aErrorCode ), RPT_SEVERITY_IGNORE,
"Missing severity from map in ERC_SETTINGS!" );
// Special-case pin-to-pin errors: // Special-case pin-to-pin errors:
// Ignore-or-not is controlled by ERCE_PIN_TO_PIN_WARNING (for both) // Ignore-or-not is controlled by ERCE_PIN_TO_PIN_WARNING (for both)
// Warning-or-error is controlled by which errorCode it is // Warning-or-error is controlled by which errorCode it is
@ -114,6 +212,9 @@ int ERC_SETTINGS::GetSeverity( int aErrorCode ) const
return RPT_SEVERITY_WARNING; return RPT_SEVERITY_WARNING;
} }
wxCHECK_MSG( m_Severities.count( aErrorCode ), RPT_SEVERITY_IGNORE,
"Missing severity from map in ERC_SETTINGS!" );
return m_Severities.at( aErrorCode ); return m_Severities.at( aErrorCode );
} }
@ -124,6 +225,12 @@ void ERC_SETTINGS::SetSeverity( int aErrorCode, int aSeverity )
} }
void ERC_SETTINGS::ResetPinMap()
{
memcpy( m_PinMap, m_defaultPinMap, sizeof( m_PinMap ) );
}
void SHEETLIST_ERC_ITEMS_PROVIDER::SetSeverities( int aSeverities ) void SHEETLIST_ERC_ITEMS_PROVIDER::SetSeverities( int aSeverities )
{ {
m_severities = aSeverities; m_severities = aSeverities;

View File

@ -21,13 +21,62 @@
#ifndef _ERC_SETTINGS_H #ifndef _ERC_SETTINGS_H
#define _ERC_SETTINGS_H #define _ERC_SETTINGS_H
#include <erc.h>
#include <erc_item.h> #include <erc_item.h>
#include <pin_type.h>
#include <settings/nested_settings.h> #include <settings/nested_settings.h>
#include <widgets/ui_common.h> #include <widgets/ui_common.h>
class SCH_MARKER; class SCH_MARKER;
class SCHEMATIC;
/// ERC error codes
enum ERCE_T
{
ERCE_UNSPECIFIED = 0,
ERCE_FIRST,
ERCE_DUPLICATE_SHEET_NAME = ERCE_FIRST, // duplicate sheet names within a given sheet
ERCE_PIN_NOT_CONNECTED, // pin not connected and not no connect symbol
ERCE_PIN_NOT_DRIVEN, // pin connected to some others pins but no pin to drive it
ERCE_HIERACHICAL_LABEL, // mismatch between hierarchical labels and pins sheets
ERCE_NOCONNECT_CONNECTED, // a no connect symbol is connected to more than 1 pin
ERCE_NOCONNECT_NOT_CONNECTED, // a no connect symbol is not connected to anything
ERCE_LABEL_NOT_CONNECTED, // label not connected to anything
ERCE_SIMILAR_LABELS, // 2 labels are equal fir case insensitive comparisons
ERCE_DIFFERENT_UNIT_FP, // different units of the same component have different footprints assigned
ERCE_DIFFERENT_UNIT_NET, // a shared pin in a multi-unit component is connected to more than one net
ERCE_BUS_ALIAS_CONFLICT, // conflicting bus alias definitions across sheets
ERCE_DRIVER_CONFLICT, // conflicting drivers (labels, etc) on a subgraph
ERCE_BUS_ENTRY_CONFLICT, // a wire connected to a bus doesn't match the bus
ERCE_BUS_LABEL_ERROR, // a label attached to a bus isn't in bus format
ERCE_BUS_TO_BUS_CONFLICT, // a connection between bus objects doesn't share at least one net
ERCE_BUS_TO_NET_CONFLICT, // a bus wire is graphically connected to a net port/pin (or vice versa)
ERCE_GLOBLABEL, // a global label is unique
ERCE_UNRESOLVED_VARIABLE,
ERCE_LAST = ERCE_UNRESOLVED_VARIABLE,
// Errors after this point will not automatically appear in the Severities Panel
ERCE_PIN_TO_PIN_WARNING, // pin connected to an other pin: warning level
ERCE_PIN_TO_PIN_ERROR, // pin connected to an other pin: error level
};
/// The values a pin-to-pin entry in the pin matrix can take on
enum class PIN_ERROR
{
OK,
WARNING,
ERROR,
UNCONNECTED
};
/// Types of drive on a net (used for legacy ERC)
#define NPI 4 // Net with Pin isolated, this pin has type Not Connected and must be left N.C.
#define DRV 3 // Net driven by a signal (a pin output for instance)
#define NET_NC 2 // Net "connected" to a "NoConnect symbol"
#define NOD 1 // Net not driven ( Such as 2 or more connected inputs )
#define NOC 0 // initial state of a net: no connection
/** /**
* Container for ERC settings * Container for ERC settings
@ -71,7 +120,49 @@ public:
void SetSeverity( int aErrorCode, int aSeverity ); void SetSeverity( int aErrorCode, int aSeverity );
void ResetPinMap();
PIN_ERROR GetPinMapValue( int aFirstType, int aSecondType ) const
{
wxASSERT( aFirstType < ELECTRICAL_PINTYPES_TOTAL
&& aSecondType < ELECTRICAL_PINTYPES_TOTAL );
return m_PinMap[aFirstType][aSecondType];
}
PIN_ERROR GetPinMapValue( ELECTRICAL_PINTYPE aFirstType, ELECTRICAL_PINTYPE aSecondType ) const
{
return m_PinMap[static_cast<int>( aFirstType )][static_cast<int>( aSecondType )];
}
void SetPinMapValue( int aFirstType, int aSecondType, PIN_ERROR aValue )
{
wxASSERT( aFirstType < ELECTRICAL_PINTYPES_TOTAL
&& aSecondType < ELECTRICAL_PINTYPES_TOTAL );
m_PinMap[aFirstType][aSecondType] = aValue;
}
void SetPinMapValue( ELECTRICAL_PINTYPE aFirstType, ELECTRICAL_PINTYPE aSecondType,
PIN_ERROR aValue )
{
m_PinMap[static_cast<int>( aFirstType )][static_cast<int>( aSecondType )] = aValue;
}
int GetPinMinDrive( ELECTRICAL_PINTYPE aFirstType, ELECTRICAL_PINTYPE aSecondType ) const
{
return m_PinMinDrive[static_cast<int>( aFirstType )][static_cast<int>( aSecondType )];
}
public:
std::map<int, int> m_Severities; std::map<int, int> m_Severities;
PIN_ERROR m_PinMap[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL];
static int m_PinMinDrive[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL];
private:
static PIN_ERROR m_defaultPinMap[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL];
}; };
/** /**

View File

@ -32,6 +32,7 @@
#include <reporter.h> #include <reporter.h>
#include <confirm.h> #include <confirm.h>
#include <kiway.h> #include <kiway.h>
#include <erc.h>
#include <netlist.h> #include <netlist.h>
#include <netlist_exporter.h> #include <netlist_exporter.h>
@ -158,10 +159,6 @@ bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileNam
} }
//Imported function:
int TestDuplicateSheetNames( SCHEMATIC* aSchematic, bool aCreateMarker );
bool SCH_EDIT_FRAME::ReadyToNetlist( bool aSilent, bool aSilentAnnotate ) bool SCH_EDIT_FRAME::ReadyToNetlist( bool aSilent, bool aSilentAnnotate )
{ {
// Ensure all power symbols have a valid reference // Ensure all power symbols have a valid reference
@ -190,7 +187,9 @@ bool SCH_EDIT_FRAME::ReadyToNetlist( bool aSilent, bool aSilentAnnotate )
} }
// Test duplicate sheet names: // Test duplicate sheet names:
if( TestDuplicateSheetNames( &Schematic(), false ) > 0 ) ERC_TESTER erc( &Schematic() );
if( erc.TestDuplicateSheetNames( false ) > 0 )
{ {
if( aSilent || !IsOK( this, _( "Error: duplicate sheet names. Continue?" ) ) ) if( aSilent || !IsOK( this, _( "Error: duplicate sheet names. Continue?" ) ) )
return false; return false;

View File

@ -831,7 +831,9 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
if( aPosition != CLEAR ) if( aPosition != CLEAR )
{ {
if( TestDuplicateSheetNames( &editFrame->Schematic(), false ) > 0 ) ERC_TESTER erc( &editFrame->Schematic() );
if( erc.TestDuplicateSheetNames( false ) > 0 )
{ {
wxMessageBox( _( "Error: duplicate sub-sheet names found in current sheet." ) ); wxMessageBox( _( "Error: duplicate sub-sheet names found in current sheet." ) );
retVal = false; retVal = false;