68 _(
"Bidirectional Pin" ),
72 _(
"Unspecified Pin" ),
73 _(
"Power Input Pin" ),
74 _(
"Power Output Pin" ),
75 _(
"Open Collector" ),
85 _(
"Bidirectional Pin" ),
89 _(
"Unspecified Pin" ),
90 _(
"Power Input Pin" ),
91 _(
"Power Output Pin" ),
92 _(
"Open Collector" ),
132 for( screen = screenList.
GetFirst(); screen !=
nullptr; screen = screenList.
GetNext() )
134 std::vector<SCH_SHEET*> list;
137 list.push_back(
static_cast<SCH_SHEET*
>( item ) );
139 for(
size_t i = 0; i < list.size(); i++ )
143 for(
size_t j = i + 1; j < list.size(); j++ )
155 ercItem->SetItems( sheet, test_item );
175 auto unresolved = [
this]( wxString str )
178 return str.Matches( wxT(
"*${*}*" ) );
209 if( unresolved( field.GetShownText(
true ) ) )
211 std::shared_ptr<ERC_ITEM> ercItem =
213 ercItem->SetItems( &field );
226 if( unresolved( field.GetShownText(
true ) ) )
228 std::shared_ptr<ERC_ITEM> ercItem =
230 ercItem->SetItems( &field );
239 if(
pin->GetShownText(
true ).Matches( wxT(
"*${*}*" ) ) )
241 std::shared_ptr<ERC_ITEM> ercItem =
243 ercItem->SetItems(
pin );
252 if(
text->GetShownText(
true ).Matches( wxT(
"*${*}*" ) ) )
254 std::shared_ptr<ERC_ITEM> ercItem =
256 ercItem->SetItems(
text );
264 if( textBox->GetShownText(
true ).Matches( wxT(
"*${*}*" ) ) )
266 std::shared_ptr<ERC_ITEM> ercItem =
268 ercItem->SetItems( textBox );
280 if(
text->GetShownText(
true ).Matches( wxT(
"*${*}*" ) ) )
283 erc->SetErrorMessage(
_(
"Unresolved text variable in drawing sheet" ) );
302 std::vector< std::shared_ptr<BUS_ALIAS> > aliases;
306 const std::set< std::shared_ptr<BUS_ALIAS> > screen_aliases = screen->GetBusAliases();
308 for(
const std::shared_ptr<BUS_ALIAS>& alias : screen_aliases )
310 std::vector<wxString> aliasMembers = alias->Members();
311 std::sort( aliasMembers.begin(), aliasMembers.end() );
313 for(
const std::shared_ptr<BUS_ALIAS>&
test : aliases )
315 std::vector<wxString> testMembers =
test->Members();
316 std::sort( testMembers.begin(), testMembers.end() );
318 if( alias->GetName() ==
test->GetName() && aliasMembers != testMembers )
320 msg.Printf(
_(
"Bus alias %s has conflicting definitions on %s and %s" ),
322 alias->GetParent()->GetFileName(),
323 test->GetParent()->GetFileName() );
326 ercItem->SetErrorMessage( msg );
329 test->GetParent()->Append( marker );
336 aliases.insert( aliases.end(), screen_aliases.begin(), screen_aliases.end() );
351 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : refMap )
366 for(
unsigned i = 0; i < refList.
GetCount(); ++i )
371 if( !unitFP.IsEmpty() )
374 unitName = unit->
GetRef( &sheetPath,
true );
379 for(
unsigned i = 0; i < refList.
GetCount(); ++i )
387 if( unit && !secondFp.IsEmpty() && unitFP != secondFp )
389 msg.Printf(
_(
"Different footprints assigned to %s and %s" ),
390 unitName, secondName );
393 ercItem->SetErrorMessage( msg );
394 ercItem->SetItems( unit, secondUnit );
417 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : refMap )
421 wxCHECK2( refList.
GetCount(),
continue );
431 std::set<int> lib_units;
432 std::set<int> instance_units;
433 std::set<int> missing_units;
435 auto report_missing = [&]( std::set<int>& aMissingUnits, wxString aErrorMsg,
int aErrorCode )
438 wxString missing_pin_units = wxT(
"[ " );
441 for(
int missing_unit : aMissingUnits )
445 missing_pin_units += wxT(
"....." );
452 missing_pin_units.Truncate( missing_pin_units.length() - 2 );
453 missing_pin_units += wxT(
" ]" );
455 msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
458 ercItem->SetErrorMessage( msg );
459 ercItem->SetItems( unit );
467 for(
int ii = 1; ii <= libSymbol->
GetUnitCount(); ++ii )
468 lib_units.insert( lib_units.end(), ii );
470 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
471 instance_units.insert( instance_units.end(), refList.
GetItem( ii ).
GetUnit() );
473 std::set_difference( lib_units.begin(), lib_units.end(),
474 instance_units.begin(), instance_units.end(),
475 std::inserter( missing_units, missing_units.begin() ) );
479 report_missing( missing_units,
_(
"Symbol %s has unplaced units %s" ),
483 std::set<int> missing_power;
484 std::set<int> missing_input;
485 std::set<int> missing_bidi;
487 for(
int missing_unit : missing_units )
492 for(
size_t ii = 0; ii < refList.
GetCount(); ++ii )
503 for(
auto pin : pins )
505 switch(
pin->GetType() )
507 case ELECTRICAL_PINTYPE::PT_POWER_IN:
508 missing_power.insert( missing_unit );
511 case ELECTRICAL_PINTYPE::PT_BIDI:
512 missing_bidi.insert( missing_unit );
515 case ELECTRICAL_PINTYPE::PT_INPUT:
516 missing_input.insert( missing_unit );
527 report_missing( missing_power,
_(
"Symbol %s has input power pins in units %s that are not placed." ),
533 report_missing( missing_input,
_(
"Symbol %s has input pins in units %s that are not placed." ),
539 report_missing( missing_bidi,
_(
"Symbol %s has bidirectional pins in units %s that are not placed." ),
554 std::map<VECTOR2I, std::vector<SCH_PIN*>> pinMap;
562 if(
pin->GetLibPin()->GetType() == ELECTRICAL_PINTYPE::PT_NC )
563 pinMap[
pin->GetPosition()].emplace_back(
pin );
567 for(
const std::pair<
const VECTOR2I, std::vector<SCH_PIN*>>& pair : pinMap )
569 if( pair.second.size() > 1 )
575 ercItem->SetItems( pair.second[0], pair.second[1],
576 pair.second.size() > 2 ? pair.second[2] :
nullptr,
577 pair.second.size() > 3 ? pair.second[3] :
nullptr );
578 ercItem->SetErrorMessage(
_(
"Pins with 'no connection' type are connected" ) );
581 sheet.LastScreen()->Append( marker );
599 std::vector<ERC_SCH_PIN_CONTEXT> pins;
600 std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
601 bool has_noconnect =
false;
606 has_noconnect =
true;
612 pins.emplace_back(
static_cast<SCH_PIN*
>( item ), subgraph->
GetSheet() );
618 std::set<std::pair<ERC_SCH_PIN_CONTEXT, ERC_SCH_PIN_CONTEXT>> tested;
621 bool hasDriver =
false;
626 bool ispowerNet =
false;
630 if( refPin.Pin()->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
646 if( !needsDriver.
Pin()
647 || ( !needsDriver.
Pin()->
IsVisible() && refPin.Pin()->IsVisible() )
650 == ELECTRICAL_PINTYPE::PT_POWER_IN )
651 && ispowerNet == ( refType == ELECTRICAL_PINTYPE::PT_POWER_IN ) ) )
653 needsDriver = refPin;
664 if( testPin == refPin )
670 if( second_pin < first_pin )
671 std::swap( first_pin, second_pin );
673 std::pair<ERC_SCH_PIN_CONTEXT, ERC_SCH_PIN_CONTEXT> pair =
674 std::make_pair( first_pin, second_pin );
676 if(
auto [ins_pin, inserted ] = tested.insert( pair ); !inserted )
682 if( refPin.Pin()->IsStacked( testPin.Pin() ) && refPin.Sheet() == testPin.Sheet() )
696 std::shared_ptr<ERC_ITEM> ercItem =
699 ercItem->SetItems( refPin.Pin(), testPin.Pin() );
700 ercItem->SetSheetSpecificPath( refPin.Sheet() );
701 ercItem->SetItemsSheetPaths( refPin.Sheet(), testPin.Sheet() );
703 ercItem->SetErrorMessage(
704 wxString::Format(
_(
"Pins of type %s and %s are connected" ),
709 new SCH_MARKER( ercItem, refPin.Pin()->GetTransformedPosition() );
710 pinToScreenMap[refPin.Pin()]->Append( marker );
716 if( needsDriver.
Pin() && !hasDriver && !has_noconnect )
724 ercItem->SetItems( needsDriver.
Pin() );
725 ercItem->SetSheetSpecificPath( needsDriver.
Sheet() );
726 ercItem->SetItemsSheetPaths( needsDriver.
Sheet() );
730 pinToScreenMap[needsDriver.
Pin()]->Append( marker );
746 std::unordered_map<wxString, std::pair<wxString, SCH_PIN*>> pinToNetMap;
750 const wxString& netName = net.first.Name;
761 if( !
pin->GetLibPin()->GetParent()->IsMulti() )
764 wxString
name =
pin->GetParentSymbol()->GetRef( &sheet ) +
765 +
":" +
pin->GetShownNumber();
767 if( !pinToNetMap.count(
name ) )
769 pinToNetMap[
name] = std::make_pair( netName,
pin );
771 else if( pinToNetMap[
name].first != netName )
773 std::shared_ptr<ERC_ITEM> ercItem =
776 ercItem->SetErrorMessage( wxString::Format(
777 _(
"Pin %s is connected to both %s and %s" ),
778 pin->GetShownNumber(),
780 pinToNetMap[
name].first ) );
782 ercItem->SetItems(
pin, pinToNetMap[
name].second );
783 ercItem->SetSheetSpecificPath( sheet );
784 ercItem->SetItemsSheetPaths( sheet, sheet );
787 pin->GetTransformedPosition() );
806 std::unordered_map<wxString, std::pair<SCH_LABEL_BASE*, SCH_SHEET_PATH>> labelMap;
814 switch( item->Type() )
822 wxString normalized = label->
GetShownText(
false ).Lower();
824 if( !labelMap.count( normalized ) )
826 labelMap[normalized] = std::make_pair( label, subgraph->
GetSheet() );
828 else if( labelMap.at( normalized ).first->GetShownText(
false )
832 ercItem->SetItems( label, labelMap.at( normalized ).first );
833 ercItem->SetSheetSpecificPath( subgraph->
GetSheet() );
834 ercItem->SetItemsSheetPaths( subgraph->
GetSheet(),
835 labelMap.
at( normalized ).second );
868 std::vector<SCH_MARKER*> markers;
875 wxCHECK2( libSymbolInSchematic,
continue );
883 ercItem->SetItems( symbol );
884 msg.Printf(
_(
"The current configuration does not include the library '%s'" ),
886 ercItem->SetErrorMessage( msg );
891 else if( !libTable->
HasLibrary( libName,
true ) )
894 ercItem->SetItems( symbol );
895 msg.Printf(
_(
"The library '%s' is not enabled in the current configuration" ),
897 ercItem->SetErrorMessage( msg );
906 if( libSymbol ==
nullptr )
909 ercItem->SetItems( symbol );
910 msg.Printf(
_(
"Symbol '%s' not found in symbol library '%s'" ),
913 ercItem->SetErrorMessage( msg );
919 std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->
Flatten();
922 if( flattenedSymbol->Compare( *libSymbolInSchematic, flags ) != 0 )
925 ercItem->SetItems( symbol );
926 msg.Printf(
_(
"Symbol '%s' has been modified in library '%s'" ),
929 ercItem->SetErrorMessage( msg );
937 screen->Append( marker );
954 const int clamped_grid_size = ( aGridSize < min_grid_size ) ? min_grid_size : aGridSize;
961 std::vector<SCH_MARKER*> markers;
963 for(
SCH_ITEM* item : screen->Items() )
965 if( item->Type() ==
SCH_LINE_T && item->IsConnectable() )
973 ercItem->SetItems( line );
977 else if( ( line->
GetEndPoint().
x % clamped_grid_size ) != 0
981 ercItem->SetItems( line );
994 if( ( pinPos.
x % clamped_grid_size ) != 0
995 || ( pinPos.
y % clamped_grid_size) != 0 )
998 ercItem->SetItems(
pin );
1000 markers.emplace_back(
new SCH_MARKER( ercItem, pinPos ) );
1009 screen->Append( marker );
1028 std::vector<SCH_MARKER*> markers;
1044 if( !msg.IsEmpty() )
1051 ercItem->SetErrorMessage( msg );
1052 ercItem->SetItems( symbol );
1060 sheet.LastScreen()->Append( marker );
constexpr EDA_IU_SCALE schIUScale
const NET_MAP & GetNetMap() const
A subgraph is a set of items that are electrically connected on a single sheet.
const std::vector< SCH_ITEM * > & GetItems() const
Provides a read-only reference to the items in the subgraph.
const SCH_ITEM * GetNoConnect() const
const SCH_SHEET_PATH & GetSheet() const
Base class to handle basic graphic items.
Store the list of graphic items: rect, lines, polygons and texts to draw/plot the title block and fra...
DS_DRAW_ITEM_BASE * GetFirst()
void BuildDrawItemsList(const PAGE_INFO &aPageInfo, const TITLE_BLOCK &aTitleBlock)
Drawing or plot the drawing sheet.
void SetFileName(const wxString &aFileName)
Set the filename to draw/plot.
void SetSheetName(const wxString &aSheetName)
Set the sheet name to draw/plot.
void SetSheetLayer(const wxString &aSheetLayer)
Set the sheet layer to draw/plot.
void SetSheetCount(int aSheetCount)
Set the value of the count of sheets, for basic inscriptions.
void SetPageNumber(const wxString &aPageNumber)
Set the value of the sheet number.
DS_DRAW_ITEM_BASE * GetNext()
void SetMilsToIUfactor(double aMils2Iu)
Set the scalar to convert pages units (mils) to draw/plot units.
void SetProject(const PROJECT *aProject)
const PAGE_INFO & GetPageInfo()
const TITLE_BLOCK & GetTitleBlock()
EE_TYPE OfType(KICAD_T aType) const
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
A class used to associate a SCH_PIN with its owning SCH_SHEET_PATH, in order to handle ERC checks acr...
SCH_PIN * Pin()
Gets the SCH_PIN for this context.
SCH_SHEET_PATH & Sheet()
Gets the SCH_SHEET_PATH context for the paired SCH_PIN.
Container for ERC settings.
bool IsTestEnabled(int aErrorCode) const
PIN_ERROR GetPinMapValue(int aFirstType, int aSecondType) const
int TestLibSymbolIssues()
Test symbols for changed library symbols and broken symbol library links.
void TestTextVars(DS_PROXY_VIEW_ITEM *aDrawingSheet)
Check for any unresolved text variable references.
int TestPinToPin()
Checks the full netlist against the pin-to-pin connectivity requirements.
int TestSimilarLabels()
Checks for labels that differ only in capitalization.
int TestDuplicateSheetNames(bool aCreateMarker)
Inside a given sheet, one cannot have sheets with duplicate names (file names can be duplicated).
int TestMultUnitPinConflicts()
Checks if shared pins on multi-unit symbols have been connected to different nets.
int TestOffGridEndpoints(int aGridSize)
Test pins and wire ends for being off grid.
int TestConflictingBusAliases()
Check that there are no conflicting bus alias definitions in the schematic.
int TestNoConnectPins()
In KiCad 5 and earlier, you could connect stuff up to pins with NC electrical type.
int TestSimModelIssues()
Test SPICE models for various issues.
int TestMissingUnits()
Test for uninstantiated units of multi unit symbols.
int TestMultiunitFootprints()
Test if all units of each multiunit symbol have the same footprint assigned.
const UTF8 & GetLibItemName() const
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Define a library symbol object.
wxString GetUnitDisplayName(int aUnit) override
Return the user-defined display name for aUnit for symbols with units.
int GetUnitCount() const override
For items with units, return the number of units.
void GetPins(LIB_PINS &aList, int aUnit=0, int aConvert=0) const
Return a list of pin object pointers from the draw item list.
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
SCH_SHEET_PATH & CurrentSheet() const override
CONNECTION_GRAPH * ConnectionGraph() const override
void SetCurrentSheet(const SCH_SHEET_PATH &aPath) override
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
ERC_SETTINGS & ErcSettings() const
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Base class for any item which can be embedded within the SCHEMATIC container class,...
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const override
Segment description base class to describe items which have 2 end points (track, wire,...
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
VECTOR2I GetTransformedPosition() const
ELECTRICAL_PINTYPE GetType() const
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
SCH_REFERENCE & GetItem(int aIdx)
A helper to define a symbol's reference designator in a schematic.
const SCH_SHEET_PATH & GetSheetPath() const
const wxString GetFootprint() const
SCH_SYMBOL * GetSymbol() const
LIB_SYMBOL * GetLibPart() const
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void GetMultiUnitSymbols(SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, bool aIncludePowerSymbols=true) const
Add a SCH_REFERENCE_LIST object to aRefList for each same-reference set of multi-unit parts in the li...
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SCREEN * LastScreen()
SCH_SHEET * at(size_t aIndex) const
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
std::vector< SCH_FIELD > & GetFields()
VECTOR2I GetPosition() const override
wxString GetShownName(bool aAllowExtraText) const
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve a list of the SCH_PINs for the given sheet path.
VECTOR2I GetPosition() const override
bool GetExcludeFromSim() const override
const LIB_ID & GetLibId() const
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
VECTOR2I GetPosition() const override
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, const std::vector< LIB_PIN * > &aPins)
SYMBOL_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an SYMBOL_LIB_TABLE_ROW if aNickName is found in this table or in any chained fallBack table f...
A wrapper for reporting to a wxString object.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
std::unordered_map< NET_NAME_CODE_CACHE_KEY, std::vector< CONNECTION_SUBGRAPH * > > NET_MAP
Associates a NET_CODE_NAME with all the subgraphs in that net.
const wxString CommentERC_V[]
const wxString CommentERC_H[]
const std::set< ELECTRICAL_PINTYPE > DrivenPinTypes
const std::set< ELECTRICAL_PINTYPE > DrivingPinTypes
const std::set< ELECTRICAL_PINTYPE > DrivingPowerPinTypes
@ ERCE_POWERPIN_NOT_DRIVEN
Power input pin connected to some others pins but no power out pin to drive it.
@ ERCE_MISSING_POWER_INPUT_PIN
Symbol has power input pins that are not placed on the schematic.
@ ERCE_SIMILAR_LABELS
2 labels are equal for case insensitive comparisons.
@ ERCE_ENDPOINT_OFF_GRID
Pin or wire-end off grid.
@ ERCE_DIFFERENT_UNIT_NET
Shared pin in a multi-unit symbol is connected to more than one net.
@ ERCE_UNRESOLVED_VARIABLE
A text variable could not be resolved.
@ ERCE_SIMULATION_MODEL
An error was found in the simulation model.
@ ERCE_DIFFERENT_UNIT_FP
Different units of the same symbol have different footprints assigned.
@ ERCE_NOCONNECT_CONNECTED
A no connect symbol is connected to more than 1 pin.
@ ERCE_PIN_TO_PIN_WARNING
@ ERCE_PIN_NOT_DRIVEN
Pin connected to some others pins but no pin to drive it.
@ ERCE_MISSING_INPUT_PIN
Symbol has input pins that are not placed.
@ ERCE_MISSING_UNIT
Symbol has units that are not placed on the schematic.
@ ERCE_DUPLICATE_SHEET_NAME
Duplicate sheet names within a given sheet.
@ ERCE_MISSING_BIDI_PIN
Symbol has bi-directional pins that are not placed.
@ ERCE_LIB_SYMBOL_ISSUES
Library symbol changed from current symbol in schematic or the library symbol link no longer valid.
@ ERCE_BUS_ALIAS_CONFLICT
Conflicting bus alias definitions across sheets.
PIN_ERROR
The values a pin-to-pin entry in the pin matrix can take on.
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
wxString ElectricalPinTypeGetText(ELECTRICAL_PINTYPE aType)
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
@ PT_INPUT
usual pin input: must be connected
@ PT_TRISTATE
tris state bus pin
@ PT_BIDI
input or output (like port for a microprocessor)
@ PT_POWER_OUT
output of a regulator: intended to be connected to power input pins
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin
LIB_SYMBOL * SchGetLibSymbol(const LIB_ID &aLibId, SYMBOL_LIB_TABLE *aLibTable, SYMBOL_LIB *aCacheLib, wxWindow *aParent, bool aShowErrorMsg)
Load symbol from symbol library table.
std::map< wxString, SCH_REFERENCE_LIST > SCH_MULTI_UNIT_REFERENCE_MAP
Container to map reference designators for multi-unit parts.
wxString UnescapeString(const wxString &aSource)
constexpr int MilsToIU(int mils) const