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:
parent
cf38d382c7
commit
b94e29e3b1
|
@ -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 );
|
||||||
|
|
|
@ -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 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
117
eeschema/erc.cpp
117
eeschema/erc.cpp
|
@ -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 )
|
||||||
{
|
{
|
||||||
|
|
157
eeschema/erc.h
157
eeschema/erc.h
|
@ -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
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue