KiCad PCB EDA Suite
Loading...
Searching...
No Matches
erc.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2011 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <algorithm>
27#include <numeric>
28
29#include "connection_graph.h"
30#include <common.h> // for ExpandEnvVarSubstitutions
31#include <erc.h>
32#include <erc_sch_pin_context.h>
33#include <string_utils.h>
34#include <lib_pin.h>
35#include <sch_edit_frame.h>
36#include <sch_marker.h>
37#include <sch_reference_list.h>
38#include <sch_sheet.h>
39#include <sch_sheet_pin.h>
40#include <sch_textbox.h>
41#include <sch_line.h>
42#include <schematic.h>
45#include <wx/ffile.h>
46#include <sim/sim_lib_mgr.h>
47
48
49/* ERC tests :
50 * 1 - conflicts between connected pins ( example: 2 connected outputs )
51 * 2 - minimal connections requirements ( 1 input *must* be connected to an
52 * output, or a passive pin )
53 */
54
55/*
56 * Minimal ERC requirements:
57 * All pins *must* be connected (except ELECTRICAL_PINTYPE::PT_NC).
58 * When a pin is not connected in schematic, the user must place a "non
59 * connected" symbol to this pin.
60 * This ensures a forgotten connection will be detected.
61 */
62
63// Messages for matrix rows:
64const wxString CommentERC_H[] =
65{
66 _( "Input Pin" ),
67 _( "Output Pin" ),
68 _( "Bidirectional Pin" ),
69 _( "Tri-State Pin" ),
70 _( "Passive Pin" ),
71 _( "Free Pin" ),
72 _( "Unspecified Pin" ),
73 _( "Power Input Pin" ),
74 _( "Power Output Pin" ),
75 _( "Open Collector" ),
76 _( "Open Emitter" ),
77 _( "No Connection" )
78};
79
80// Messages for matrix columns
81const wxString CommentERC_V[] =
82{
83 _( "Input Pin" ),
84 _( "Output Pin" ),
85 _( "Bidirectional Pin" ),
86 _( "Tri-State Pin" ),
87 _( "Passive Pin" ),
88 _( "Free Pin" ),
89 _( "Unspecified Pin" ),
90 _( "Power Input Pin" ),
91 _( "Power Output Pin" ),
92 _( "Open Collector" ),
93 _( "Open Emitter" ),
94 _( "No Connection" )
95};
96
97
98// List of pin types that are considered drivers for usual input pins
99// i.e. pin type = ELECTRICAL_PINTYPE::PT_INPUT, but not PT_POWER_IN
100// that need only a PT_POWER_OUT pin type to be driven
101const std::set<ELECTRICAL_PINTYPE> DrivingPinTypes =
102 {
108 };
109
110// List of pin types that are considered drivers for power pins
111// In fact only a ELECTRICAL_PINTYPE::PT_POWER_OUT pin type can drive
112// power input pins
113const std::set<ELECTRICAL_PINTYPE> DrivingPowerPinTypes =
114 {
116 };
117
118// List of pin types that require a driver elsewhere on the net
119const std::set<ELECTRICAL_PINTYPE> DrivenPinTypes =
120 {
123 };
124
125int ERC_TESTER::TestDuplicateSheetNames( bool aCreateMarker )
126{
127 SCH_SCREEN* screen;
128 int err_count = 0;
129
130 SCH_SCREENS screenList( m_schematic->Root() );
131
132 for( screen = screenList.GetFirst(); screen != nullptr; screen = screenList.GetNext() )
133 {
134 std::vector<SCH_SHEET*> list;
135
136 for( SCH_ITEM* item : screen->Items().OfType( SCH_SHEET_T ) )
137 list.push_back( static_cast<SCH_SHEET*>( item ) );
138
139 for( size_t i = 0; i < list.size(); i++ )
140 {
141 SCH_SHEET* sheet = list[i];
142
143 for( size_t j = i + 1; j < list.size(); j++ )
144 {
145 SCH_SHEET* test_item = list[j];
146
147 // We have found a second sheet: compare names
148 // we are using case insensitive comparison to avoid mistakes between
149 // similar names like Mysheet and mysheet
150 if( sheet->GetShownName( false ).CmpNoCase( test_item->GetShownName( false ) ) == 0 )
151 {
152 if( aCreateMarker )
153 {
154 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_DUPLICATE_SHEET_NAME );
155 ercItem->SetItems( sheet, test_item );
156
157 SCH_MARKER* marker = new SCH_MARKER( ercItem, sheet->GetPosition() );
158 screen->Append( marker );
159 }
160
161 err_count++;
162 }
163 }
164 }
165 }
166
167 return err_count;
168}
169
170
172{
173 DS_DRAW_ITEM_LIST wsItems;
174
175 auto unresolved = [this]( wxString str )
176 {
177 str = ExpandEnvVarSubstitutions( str, &m_schematic->Prj() );
178 return str.Matches( wxT( "*${*}*" ) );
179 };
180
181 if( aDrawingSheet )
182 {
184 wsItems.SetPageNumber( wxS( "1" ) );
185 wsItems.SetSheetCount( 1 );
186 wsItems.SetFileName( wxS( "dummyFilename" ) );
187 wsItems.SetSheetName( wxS( "dummySheet" ) );
188 wsItems.SetSheetLayer( wxS( "dummyLayer" ) );
189 wsItems.SetProject( &m_schematic->Prj() );
190 wsItems.BuildDrawItemsList( aDrawingSheet->GetPageInfo(), aDrawingSheet->GetTitleBlock());
191 }
192
193 SCH_SHEET_PATH savedCurrentSheet = m_schematic->CurrentSheet();
195
196 for( SCH_SHEET_PATH& sheet : sheets )
197 {
199 SCH_SCREEN* screen = sheet.LastScreen();
200
201 for( SCH_ITEM* item : screen->Items().OfType( SCH_LOCATE_ANY_T ) )
202 {
203 if( item->Type() == SCH_SYMBOL_T )
204 {
205 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
206
207 for( SCH_FIELD& field : symbol->GetFields() )
208 {
209 if( unresolved( field.GetShownText( true ) ) )
210 {
211 std::shared_ptr<ERC_ITEM> ercItem =
213 ercItem->SetItems( &field );
214
215 SCH_MARKER* marker = new SCH_MARKER( ercItem, field.GetPosition() );
216 screen->Append( marker );
217 }
218 }
219 }
220 else if( item->Type() == SCH_SHEET_T )
221 {
222 SCH_SHEET* subSheet = static_cast<SCH_SHEET*>( item );
223
224 for( SCH_FIELD& field : subSheet->GetFields() )
225 {
226 if( unresolved( field.GetShownText( true ) ) )
227 {
228 std::shared_ptr<ERC_ITEM> ercItem =
230 ercItem->SetItems( &field );
231
232 SCH_MARKER* marker = new SCH_MARKER( ercItem, field.GetPosition() );
233 screen->Append( marker );
234 }
235 }
236
237 for( SCH_SHEET_PIN* pin : static_cast<SCH_SHEET*>( item )->GetPins() )
238 {
239 if( pin->GetShownText( true ).Matches( wxT( "*${*}*" ) ) )
240 {
241 std::shared_ptr<ERC_ITEM> ercItem =
243 ercItem->SetItems( pin );
244
245 SCH_MARKER* marker = new SCH_MARKER( ercItem, pin->GetPosition() );
246 screen->Append( marker );
247 }
248 }
249 }
250 else if( SCH_TEXT* text = dynamic_cast<SCH_TEXT*>( item ) )
251 {
252 if( text->GetShownText( true ).Matches( wxT( "*${*}*" ) ) )
253 {
254 std::shared_ptr<ERC_ITEM> ercItem =
256 ercItem->SetItems( text );
257
258 SCH_MARKER* marker = new SCH_MARKER( ercItem, text->GetPosition() );
259 screen->Append( marker );
260 }
261 }
262 else if( SCH_TEXTBOX* textBox = dynamic_cast<SCH_TEXTBOX*>( item ) )
263 {
264 if( textBox->GetShownText( true ).Matches( wxT( "*${*}*" ) ) )
265 {
266 std::shared_ptr<ERC_ITEM> ercItem =
268 ercItem->SetItems( textBox );
269
270 SCH_MARKER* marker = new SCH_MARKER( ercItem, textBox->GetPosition() );
271 screen->Append( marker );
272 }
273 }
274 }
275
276 for( DS_DRAW_ITEM_BASE* item = wsItems.GetFirst(); item; item = wsItems.GetNext() )
277 {
278 if( DS_DRAW_ITEM_TEXT* text = dynamic_cast<DS_DRAW_ITEM_TEXT*>( item ) )
279 {
280 if( text->GetShownText( true ).Matches( wxT( "*${*}*" ) ) )
281 {
282 std::shared_ptr<ERC_ITEM> erc = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
283 erc->SetErrorMessage( _( "Unresolved text variable in drawing sheet" ) );
284
285 SCH_MARKER* marker = new SCH_MARKER( erc, text->GetPosition() );
286 screen->Append( marker );
287 }
288 }
289 }
290 }
291
292 m_schematic->SetCurrentSheet( savedCurrentSheet );
293}
294
295
297{
298 wxString msg;
299 int err_count = 0;
300
301 SCH_SCREENS screens( m_schematic->Root() );
302 std::vector< std::shared_ptr<BUS_ALIAS> > aliases;
303
304 for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
305 {
306 const std::set< std::shared_ptr<BUS_ALIAS> > screen_aliases = screen->GetBusAliases();
307
308 for( const std::shared_ptr<BUS_ALIAS>& alias : screen_aliases )
309 {
310 std::vector<wxString> aliasMembers = alias->Members();
311 std::sort( aliasMembers.begin(), aliasMembers.end() );
312
313 for( const std::shared_ptr<BUS_ALIAS>& test : aliases )
314 {
315 std::vector<wxString> testMembers = test->Members();
316 std::sort( testMembers.begin(), testMembers.end() );
317
318 if( alias->GetName() == test->GetName() && aliasMembers != testMembers )
319 {
320 msg.Printf( _( "Bus alias %s has conflicting definitions on %s and %s" ),
321 alias->GetName(),
322 alias->GetParent()->GetFileName(),
323 test->GetParent()->GetFileName() );
324
325 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_BUS_ALIAS_CONFLICT );
326 ercItem->SetErrorMessage( msg );
327
328 SCH_MARKER* marker = new SCH_MARKER( ercItem, VECTOR2I() );
329 test->GetParent()->Append( marker );
330
331 ++err_count;
332 }
333 }
334 }
335
336 aliases.insert( aliases.end(), screen_aliases.begin(), screen_aliases.end() );
337 }
338
339 return err_count;
340}
341
342
344{
346
347 int errors = 0;
349 sheets.GetMultiUnitSymbols( refMap, true );
350
351 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : refMap )
352 {
353 SCH_REFERENCE_LIST& refList = symbol.second;
354
355 if( refList.GetCount() == 0 )
356 {
357 wxFAIL; // it should not happen
358 continue;
359 }
360
361 // Reference footprint
362 SCH_SYMBOL* unit = nullptr;
363 wxString unitName;
364 wxString unitFP;
365
366 for( unsigned i = 0; i < refList.GetCount(); ++i )
367 {
368 SCH_SHEET_PATH sheetPath = refList.GetItem( i ).GetSheetPath();
369 unitFP = refList.GetItem( i ).GetFootprint();
370
371 if( !unitFP.IsEmpty() )
372 {
373 unit = refList.GetItem( i ).GetSymbol();
374 unitName = unit->GetRef( &sheetPath, true );
375 break;
376 }
377 }
378
379 for( unsigned i = 0; i < refList.GetCount(); ++i )
380 {
381 SCH_REFERENCE& secondRef = refList.GetItem( i );
382 SCH_SYMBOL* secondUnit = secondRef.GetSymbol();
383 wxString secondName = secondUnit->GetRef( &secondRef.GetSheetPath(), true );
384 const wxString secondFp = secondRef.GetFootprint();
385 wxString msg;
386
387 if( unit && !secondFp.IsEmpty() && unitFP != secondFp )
388 {
389 msg.Printf( _( "Different footprints assigned to %s and %s" ),
390 unitName, secondName );
391
392 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_DIFFERENT_UNIT_FP );
393 ercItem->SetErrorMessage( msg );
394 ercItem->SetItems( unit, secondUnit );
395
396 SCH_MARKER* marker = new SCH_MARKER( ercItem, secondUnit->GetPosition() );
397 secondRef.GetSheetPath().LastScreen()->Append( marker );
398
399 ++errors;
400 }
401 }
402 }
403
404 return errors;
405}
406
407
409{
410 ERC_SETTINGS& settings = m_schematic->ErcSettings();
412
413 int errors = 0;
415 sheets.GetMultiUnitSymbols( refMap, true );
416
417 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : refMap )
418 {
419 SCH_REFERENCE_LIST& refList = symbol.second;
420
421 wxCHECK2( refList.GetCount(), continue );
422
423 // Reference unit
424 SCH_REFERENCE& base_ref = refList.GetItem( 0 );
425 SCH_SYMBOL* unit = base_ref.GetSymbol();
426 LIB_SYMBOL* libSymbol = base_ref.GetLibPart();
427
428 if( static_cast<ssize_t>( refList.GetCount() ) == libSymbol->GetUnitCount() )
429 continue;
430
431 std::set<int> lib_units;
432 std::set<int> instance_units;
433 std::set<int> missing_units;
434
435 auto report_missing = [&]( std::set<int>& aMissingUnits, wxString aErrorMsg, int aErrorCode )
436 {
437 wxString msg;
438 wxString missing_pin_units = wxT( "[ " );
439 int ii = 0;
440
441 for( int missing_unit : aMissingUnits )
442 {
443 if( ii++ == 3 )
444 {
445 missing_pin_units += wxT( "....." );
446 break;
447 }
448
449 missing_pin_units += libSymbol->GetUnitDisplayName( missing_unit ) + ", " ;
450 }
451
452 missing_pin_units.Truncate( missing_pin_units.length() - 2 );
453 missing_pin_units += wxT( " ]" );
454
455 msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
456
457 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( aErrorCode );
458 ercItem->SetErrorMessage( msg );
459 ercItem->SetItems( unit );
460
461 SCH_MARKER* marker = new SCH_MARKER( ercItem, unit->GetPosition() );
462 base_ref.GetSheetPath().LastScreen()->Append( marker );
463
464 ++errors;
465 };
466
467 for( int ii = 1; ii <= libSymbol->GetUnitCount(); ++ii )
468 lib_units.insert( lib_units.end(), ii );
469
470 for( size_t ii = 0; ii < refList.GetCount(); ++ii )
471 instance_units.insert( instance_units.end(), refList.GetItem( ii ).GetUnit() );
472
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() ) );
476
477 if( !missing_units.empty() && settings.IsTestEnabled( ERCE_MISSING_UNIT ) )
478 {
479 report_missing( missing_units, _( "Symbol %s has unplaced units %s" ),
481 }
482
483 std::set<int> missing_power;
484 std::set<int> missing_input;
485 std::set<int> missing_bidi;
486
487 for( int missing_unit : missing_units )
488 {
489 LIB_PINS pins;
490 int convert = 0;
491
492 for( size_t ii = 0; ii < refList.GetCount(); ++ii )
493 {
494 if( refList.GetItem( ii ).GetUnit() == missing_unit )
495 {
496 convert = refList.GetItem( ii ).GetSymbol()->GetConvert();
497 break;
498 }
499 }
500
501 libSymbol->GetPins( pins, missing_unit, convert );
502
503 for( auto pin : pins )
504 {
505 switch( pin->GetType() )
506 {
507 case ELECTRICAL_PINTYPE::PT_POWER_IN:
508 missing_power.insert( missing_unit );
509 break;
510
511 case ELECTRICAL_PINTYPE::PT_BIDI:
512 missing_bidi.insert( missing_unit );
513 break;
514
515 case ELECTRICAL_PINTYPE::PT_INPUT:
516 missing_input.insert( missing_unit );
517 break;
518
519 default:
520 break;
521 }
522 }
523 }
524
525 if( !missing_power.empty() && settings.IsTestEnabled( ERCE_MISSING_POWER_INPUT_PIN ) )
526 {
527 report_missing( missing_power, _( "Symbol %s has input power pins in units %s that are not placed." ),
529 }
530
531 if( !missing_input.empty() && settings.IsTestEnabled( ERCE_MISSING_INPUT_PIN ) )
532 {
533 report_missing( missing_input, _( "Symbol %s has input pins in units %s that are not placed." ),
535 }
536
537 if( !missing_bidi.empty() && settings.IsTestEnabled( ERCE_MISSING_BIDI_PIN ) )
538 {
539 report_missing( missing_bidi, _( "Symbol %s has bidirectional pins in units %s that are not placed." ),
541 }
542 }
543
544 return errors;
545}
546
547
549{
550 int err_count = 0;
551
552 for( const SCH_SHEET_PATH& sheet : m_schematic->GetSheets() )
553 {
554 std::map<VECTOR2I, std::vector<SCH_PIN*>> pinMap;
555
556 for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
557 {
558 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
559
560 for( SCH_PIN* pin : symbol->GetPins( &sheet ) )
561 {
562 if( pin->GetLibPin()->GetType() == ELECTRICAL_PINTYPE::PT_NC )
563 pinMap[pin->GetPosition()].emplace_back( pin );
564 }
565 }
566
567 for( const std::pair<const VECTOR2I, std::vector<SCH_PIN*>>& pair : pinMap )
568 {
569 if( pair.second.size() > 1 )
570 {
571 err_count++;
572
573 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_NOCONNECT_CONNECTED );
574
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" ) );
579
580 SCH_MARKER* marker = new SCH_MARKER( ercItem, pair.first );
581 sheet.LastScreen()->Append( marker );
582 }
583 }
584 }
585
586 return err_count;
587}
588
589
591{
592 ERC_SETTINGS& settings = m_schematic->ErcSettings();
593 const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
594
595 int errors = 0;
596
597 for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
598 {
599 std::vector<ERC_SCH_PIN_CONTEXT> pins;
600 std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
601 bool has_noconnect = false;
602
603 for( CONNECTION_SUBGRAPH* subgraph: net.second )
604 {
605 if( subgraph->GetNoConnect() )
606 has_noconnect = true;
607
608 for( SCH_ITEM* item : subgraph->GetItems() )
609 {
610 if( item->Type() == SCH_PIN_T )
611 {
612 pins.emplace_back( static_cast<SCH_PIN*>( item ), subgraph->GetSheet() );
613 pinToScreenMap[item] = subgraph->GetSheet().LastScreen();
614 }
615 }
616 }
617
618 std::set<std::pair<ERC_SCH_PIN_CONTEXT, ERC_SCH_PIN_CONTEXT>> tested;
619
620 ERC_SCH_PIN_CONTEXT needsDriver;
621 bool hasDriver = false;
622
623 // We need different drivers for power nets and normal nets.
624 // A power net has at least one pin having the ELECTRICAL_PINTYPE::PT_POWER_IN
625 // and power nets can be driven only by ELECTRICAL_PINTYPE::PT_POWER_OUT pins
626 bool ispowerNet = false;
627
628 for( ERC_SCH_PIN_CONTEXT& refPin : pins )
629 {
630 if( refPin.Pin()->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
631 {
632 ispowerNet = true;
633 break;
634 }
635 }
636
637 for( ERC_SCH_PIN_CONTEXT& refPin : pins )
638 {
639 ELECTRICAL_PINTYPE refType = refPin.Pin()->GetType();
640
641 if( DrivenPinTypes.count( refType ) )
642 {
643 // needsDriver will be the pin shown in the error report eventually, so try to
644 // upgrade to a "better" pin if possible: something visible and only a power symbol
645 // if this net needs a power driver
646 if( !needsDriver.Pin()
647 || ( !needsDriver.Pin()->IsVisible() && refPin.Pin()->IsVisible() )
648 || ( ispowerNet
649 != ( needsDriver.Pin()->GetType()
650 == ELECTRICAL_PINTYPE::PT_POWER_IN )
651 && ispowerNet == ( refType == ELECTRICAL_PINTYPE::PT_POWER_IN ) ) )
652 {
653 needsDriver = refPin;
654 }
655 }
656
657 if( ispowerNet )
658 hasDriver |= ( DrivingPowerPinTypes.count( refType ) != 0 );
659 else
660 hasDriver |= ( DrivingPinTypes.count( refType ) != 0 );
661
662 for( ERC_SCH_PIN_CONTEXT& testPin : pins )
663 {
664 if( testPin == refPin )
665 continue;
666
667 ERC_SCH_PIN_CONTEXT first_pin = refPin;
668 ERC_SCH_PIN_CONTEXT second_pin = testPin;
669
670 if( second_pin < first_pin )
671 std::swap( first_pin, second_pin );
672
673 std::pair<ERC_SCH_PIN_CONTEXT, ERC_SCH_PIN_CONTEXT> pair =
674 std::make_pair( first_pin, second_pin );
675
676 if( auto [ins_pin, inserted ] = tested.insert( pair ); !inserted )
677 continue;
678
679 // Multiple pins in the same symbol that share a type,
680 // name and position are considered
681 // "stacked" and shouldn't trigger ERC errors
682 if( refPin.Pin()->IsStacked( testPin.Pin() ) && refPin.Sheet() == testPin.Sheet() )
683 continue;
684
685 ELECTRICAL_PINTYPE testType = testPin.Pin()->GetType();
686
687 if( ispowerNet )
688 hasDriver |= ( DrivingPowerPinTypes.count( testType ) != 0 );
689 else
690 hasDriver |= ( DrivingPinTypes.count( testType ) != 0 );
691
692 PIN_ERROR erc = settings.GetPinMapValue( refType, testType );
693
694 if( erc != PIN_ERROR::OK && settings.IsTestEnabled( ERCE_PIN_TO_PIN_WARNING ) )
695 {
696 std::shared_ptr<ERC_ITEM> ercItem =
697 ERC_ITEM::Create( erc == PIN_ERROR::WARNING ? ERCE_PIN_TO_PIN_WARNING :
699 ercItem->SetItems( refPin.Pin(), testPin.Pin() );
700 ercItem->SetSheetSpecificPath( refPin.Sheet() );
701 ercItem->SetItemsSheetPaths( refPin.Sheet(), testPin.Sheet() );
702
703 ercItem->SetErrorMessage(
704 wxString::Format( _( "Pins of type %s and %s are connected" ),
705 ElectricalPinTypeGetText( refType ),
706 ElectricalPinTypeGetText( testType ) ) );
707
708 SCH_MARKER* marker =
709 new SCH_MARKER( ercItem, refPin.Pin()->GetTransformedPosition() );
710 pinToScreenMap[refPin.Pin()]->Append( marker );
711 errors++;
712 }
713 }
714 }
715
716 if( needsDriver.Pin() && !hasDriver && !has_noconnect )
717 {
718 int err_code = ispowerNet ? ERCE_POWERPIN_NOT_DRIVEN : ERCE_PIN_NOT_DRIVEN;
719
720 if( settings.IsTestEnabled( err_code ) )
721 {
722 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( err_code );
723
724 ercItem->SetItems( needsDriver.Pin() );
725 ercItem->SetSheetSpecificPath( needsDriver.Sheet() );
726 ercItem->SetItemsSheetPaths( needsDriver.Sheet() );
727
728 SCH_MARKER* marker =
729 new SCH_MARKER( ercItem, needsDriver.Pin()->GetTransformedPosition() );
730 pinToScreenMap[needsDriver.Pin()]->Append( marker );
731 errors++;
732 }
733 }
734 }
735
736 return errors;
737}
738
739
741{
742 const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
743
744 int errors = 0;
745
746 std::unordered_map<wxString, std::pair<wxString, SCH_PIN*>> pinToNetMap;
747
748 for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
749 {
750 const wxString& netName = net.first.Name;
751
752 for( CONNECTION_SUBGRAPH* subgraph : net.second )
753 {
754 for( SCH_ITEM* item : subgraph->GetItems() )
755 {
756 if( item->Type() == SCH_PIN_T )
757 {
758 SCH_PIN* pin = static_cast<SCH_PIN*>( item );
759 const SCH_SHEET_PATH& sheet = subgraph->GetSheet();
760
761 if( !pin->GetLibPin()->GetParent()->IsMulti() )
762 continue;
763
764 wxString name = pin->GetParentSymbol()->GetRef( &sheet ) +
765 + ":" + pin->GetShownNumber();
766
767 if( !pinToNetMap.count( name ) )
768 {
769 pinToNetMap[name] = std::make_pair( netName, pin );
770 }
771 else if( pinToNetMap[name].first != netName )
772 {
773 std::shared_ptr<ERC_ITEM> ercItem =
775
776 ercItem->SetErrorMessage( wxString::Format(
777 _( "Pin %s is connected to both %s and %s" ),
778 pin->GetShownNumber(),
779 netName,
780 pinToNetMap[name].first ) );
781
782 ercItem->SetItems( pin, pinToNetMap[name].second );
783 ercItem->SetSheetSpecificPath( sheet );
784 ercItem->SetItemsSheetPaths( sheet, sheet );
785
786 SCH_MARKER* marker = new SCH_MARKER( ercItem,
787 pin->GetTransformedPosition() );
788 sheet.LastScreen()->Append( marker );
789 errors += 1;
790 }
791 }
792 }
793 }
794 }
795
796 return errors;
797}
798
799
801{
802 const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
803
804 int errors = 0;
805
806 std::unordered_map<wxString, std::pair<SCH_LABEL_BASE*, SCH_SHEET_PATH>> labelMap;
807
808 for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
809 {
810 for( CONNECTION_SUBGRAPH* subgraph : net.second )
811 {
812 for( SCH_ITEM* item : subgraph->GetItems() )
813 {
814 switch( item->Type() )
815 {
816 case SCH_LABEL_T:
817 case SCH_HIER_LABEL_T:
819 {
820 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( item );
821
822 wxString normalized = label->GetShownText( false ).Lower();
823
824 if( !labelMap.count( normalized ) )
825 {
826 labelMap[normalized] = std::make_pair( label, subgraph->GetSheet() );
827 }
828 else if( labelMap.at( normalized ).first->GetShownText( false )
829 != label->GetShownText( false ) )
830 {
831 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_SIMILAR_LABELS );
832 ercItem->SetItems( label, labelMap.at( normalized ).first );
833 ercItem->SetSheetSpecificPath( subgraph->GetSheet() );
834 ercItem->SetItemsSheetPaths( subgraph->GetSheet(),
835 labelMap.at( normalized ).second );
836
837 SCH_MARKER* marker = new SCH_MARKER( ercItem, label->GetPosition() );
838 subgraph->GetSheet().LastScreen()->Append( marker );
839 errors += 1;
840 }
841
842 break;
843 }
844
845 default:
846 break;
847 }
848 }
849 }
850 }
851
852 return errors;
853}
854
855
857{
858 wxCHECK( m_schematic, 0 );
859
860 SYMBOL_LIB_TABLE* libTable = m_schematic->Prj().SchSymbolLibTable();
861 wxString msg;
862 int err_count = 0;
863
864 SCH_SCREENS screens( m_schematic->Root() );
865
866 for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
867 {
868 std::vector<SCH_MARKER*> markers;
869
870 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
871 {
872 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
873 LIB_SYMBOL* libSymbolInSchematic = symbol->GetLibSymbolRef().get();
874
875 wxCHECK2( libSymbolInSchematic, continue );
876
877 wxString libName = symbol->GetLibId().GetLibNickname();
878 LIB_TABLE_ROW* libTableRow = libTable->FindRow( libName, true );
879
880 if( !libTableRow )
881 {
882 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LIB_SYMBOL_ISSUES );
883 ercItem->SetItems( symbol );
884 msg.Printf( _( "The current configuration does not include the library '%s'" ),
885 UnescapeString( libName ) );
886 ercItem->SetErrorMessage( msg );
887
888 markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
889 continue;
890 }
891 else if( !libTable->HasLibrary( libName, true ) )
892 {
893 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LIB_SYMBOL_ISSUES );
894 ercItem->SetItems( symbol );
895 msg.Printf( _( "The library '%s' is not enabled in the current configuration" ),
896 UnescapeString( libName ) );
897 ercItem->SetErrorMessage( msg );
898
899 markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
900 continue;
901 }
902
903 wxString symbolName = symbol->GetLibId().GetLibItemName();
904 LIB_SYMBOL* libSymbol = SchGetLibSymbol( symbol->GetLibId(), libTable );
905
906 if( libSymbol == nullptr )
907 {
908 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LIB_SYMBOL_ISSUES );
909 ercItem->SetItems( symbol );
910 msg.Printf( _( "Symbol '%s' not found in symbol library '%s'" ),
911 UnescapeString( symbolName ),
912 UnescapeString( libName ) );
913 ercItem->SetErrorMessage( msg );
914
915 markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
916 continue;
917 }
918
919 std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
921
922 if( flattenedSymbol->Compare( *libSymbolInSchematic, flags ) != 0 )
923 {
924 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LIB_SYMBOL_ISSUES );
925 ercItem->SetItems( symbol );
926 msg.Printf( _( "Symbol '%s' has been modified in library '%s'" ),
927 UnescapeString( symbolName ),
928 UnescapeString( libName ) );
929 ercItem->SetErrorMessage( msg );
930
931 markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
932 }
933 }
934
935 for( SCH_MARKER* marker : markers )
936 {
937 screen->Append( marker );
938 err_count += 1;
939 }
940 }
941
942 return err_count;
943}
944
945
947{
948 // The minimal grid size allowed to place a pin is 25 mils
949 // the best grid size is 50 mils, but 25 mils is still usable
950 // this is because all symbols are using a 50 mils grid to place pins, and therefore
951 // the wires must be on the 50 mils grid
952 // So raise an error if a pin is not on a 25 mil (or bigger: 50 mil or 100 mil) grid
953 const int min_grid_size = schIUScale.MilsToIU( 25 );
954 const int clamped_grid_size = ( aGridSize < min_grid_size ) ? min_grid_size : aGridSize;
955
956 SCH_SCREENS screens( m_schematic->Root() );
957 int err_count = 0;
958
959 for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
960 {
961 std::vector<SCH_MARKER*> markers;
962
963 for( SCH_ITEM* item : screen->Items() )
964 {
965 if( item->Type() == SCH_LINE_T && item->IsConnectable() )
966 {
967 SCH_LINE* line = static_cast<SCH_LINE*>( item );
968
969 if( ( line->GetStartPoint().x % clamped_grid_size ) != 0
970 || ( line->GetStartPoint().y % clamped_grid_size) != 0 )
971 {
972 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_ENDPOINT_OFF_GRID );
973 ercItem->SetItems( line );
974
975 markers.emplace_back( new SCH_MARKER( ercItem, line->GetStartPoint() ) );
976 }
977 else if( ( line->GetEndPoint().x % clamped_grid_size ) != 0
978 || ( line->GetEndPoint().y % clamped_grid_size) != 0 )
979 {
980 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_ENDPOINT_OFF_GRID );
981 ercItem->SetItems( line );
982
983 markers.emplace_back( new SCH_MARKER( ercItem, line->GetEndPoint() ) );
984 }
985 }
986 else if( item->Type() == SCH_SYMBOL_T )
987 {
988 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
989
990 for( SCH_PIN* pin : symbol->GetPins( nullptr ) )
991 {
992 VECTOR2I pinPos = pin->GetTransformedPosition();
993
994 if( ( pinPos.x % clamped_grid_size ) != 0
995 || ( pinPos.y % clamped_grid_size) != 0 )
996 {
997 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_ENDPOINT_OFF_GRID );
998 ercItem->SetItems( pin );
999
1000 markers.emplace_back( new SCH_MARKER( ercItem, pinPos ) );
1001 break;
1002 }
1003 }
1004 }
1005 }
1006
1007 for( SCH_MARKER* marker : markers )
1008 {
1009 screen->Append( marker );
1010 err_count += 1;
1011 }
1012 }
1013
1014 return err_count;
1015}
1016
1017
1019{
1020 wxString msg;
1021 WX_STRING_REPORTER reporter( &msg );
1023 int err_count = 0;
1024 SIM_LIB_MGR libMgr( &m_schematic->Prj(), &reporter );
1025
1026 for( SCH_SHEET_PATH& sheet : sheets )
1027 {
1028 std::vector<SCH_MARKER*> markers;
1029
1030 for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
1031 {
1032 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1033
1034 // Power symbols and other symbols which have the reference starting with "#" are
1035 // not included in simulation
1036 if( symbol->GetRef( &sheet ).StartsWith( '#' ) || symbol->GetExcludeFromSim() )
1037 continue;
1038
1039 // Reset for each symbol
1040 msg.Clear();
1041
1042 SIM_LIBRARY::MODEL model = libMgr.CreateModel( &sheet, *symbol );
1043
1044 if( !msg.IsEmpty() )
1045 {
1046 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_SIMULATION_MODEL );
1047
1048 //Remove \n and \r at e.o.l if any:
1049 msg.Trim();
1050
1051 ercItem->SetErrorMessage( msg );
1052 ercItem->SetItems( symbol );
1053
1054 markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
1055 }
1056 }
1057
1058 for( SCH_MARKER* marker : markers )
1059 {
1060 sheet.LastScreen()->Append( marker );
1061 err_count += 1;
1062 }
1063 }
1064
1065 return err_count;
1066}
const char * name
Definition: DXF_plotter.cpp:56
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
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.
Definition: ds_draw_item.h:59
Store the list of graphic items: rect, lines, polygons and texts to draw/plot the title block and fra...
Definition: ds_draw_item.h:395
DS_DRAW_ITEM_BASE * GetFirst()
Definition: ds_draw_item.h:493
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.
Definition: ds_draw_item.h:437
void SetSheetName(const wxString &aSheetName)
Set the sheet name to draw/plot.
Definition: ds_draw_item.h:442
void SetSheetLayer(const wxString &aSheetLayer)
Set the sheet layer to draw/plot.
Definition: ds_draw_item.h:452
void SetSheetCount(int aSheetCount)
Set the value of the count of sheets, for basic inscriptions.
Definition: ds_draw_item.h:480
void SetPageNumber(const wxString &aPageNumber)
Set the value of the sheet number.
Definition: ds_draw_item.h:470
DS_DRAW_ITEM_BASE * GetNext()
Definition: ds_draw_item.h:503
void SetMilsToIUfactor(double aMils2Iu)
Set the scalar to convert pages units (mils) to draw/plot units.
Definition: ds_draw_item.h:460
void SetProject(const PROJECT *aProject)
Definition: ds_draw_item.h:417
A graphic text.
Definition: ds_draw_item.h:311
const PAGE_INFO & GetPageInfo()
const TITLE_BLOCK & GetTitleBlock()
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:238
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:232
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.
Definition: erc_settings.h:114
bool IsTestEnabled(int aErrorCode) const
Definition: erc_settings.h:130
PIN_ERROR GetPinMapValue(int aFirstType, int aSecondType) const
Definition: erc_settings.h:141
int TestLibSymbolIssues()
Test symbols for changed library symbols and broken symbol library links.
Definition: erc.cpp:856
void TestTextVars(DS_PROXY_VIEW_ITEM *aDrawingSheet)
Check for any unresolved text variable references.
Definition: erc.cpp:171
int TestPinToPin()
Checks the full netlist against the pin-to-pin connectivity requirements.
Definition: erc.cpp:590
int TestSimilarLabels()
Checks for labels that differ only in capitalization.
Definition: erc.cpp:800
int TestDuplicateSheetNames(bool aCreateMarker)
Inside a given sheet, one cannot have sheets with duplicate names (file names can be duplicated).
Definition: erc.cpp:125
int TestMultUnitPinConflicts()
Checks if shared pins on multi-unit symbols have been connected to different nets.
Definition: erc.cpp:740
int TestOffGridEndpoints(int aGridSize)
Test pins and wire ends for being off grid.
Definition: erc.cpp:946
int TestConflictingBusAliases()
Check that there are no conflicting bus alias definitions in the schematic.
Definition: erc.cpp:296
int TestNoConnectPins()
In KiCad 5 and earlier, you could connect stuff up to pins with NC electrical type.
Definition: erc.cpp:548
int TestSimModelIssues()
Test SPICE models for various issues.
Definition: erc.cpp:1018
SCHEMATIC * m_schematic
Definition: erc.h:148
int TestMissingUnits()
Test for uninstantiated units of multi unit symbols.
Definition: erc.cpp:408
int TestMultiunitFootprints()
Test if all units of each multiunit symbol have the same footprint assigned.
Definition: erc.cpp:343
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
@ EQUALITY
Definition: lib_item.h:85
Define a library symbol object.
Definition: lib_symbol.h:99
wxString GetUnitDisplayName(int aUnit) override
Return the user-defined display name for aUnit for symbols with units.
Definition: lib_symbol.cpp:534
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.
Definition: lib_symbol.cpp:971
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:588
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
Definition: schematic.h:133
CONNECTION_GRAPH * ConnectionGraph() const override
Definition: schematic.h:143
void SetCurrentSheet(const SCH_SHEET_PATH &aPath) override
Definition: schematic.h:138
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:97
SCH_SHEET & Root() const
Definition: schematic.h:102
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:87
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:212
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:51
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const override
Definition: sch_label.cpp:694
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:40
VECTOR2I GetEndPoint() const
Definition: sch_line.h:143
VECTOR2I GetStartPoint() const
Definition: sch_line.h:138
bool IsVisible() const
Definition: sch_pin.h:135
VECTOR2I GetTransformedPosition() const
Definition: sch_pin.cpp:358
ELECTRICAL_PINTYPE GetType() const
Definition: sch_pin.cpp:117
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
size_t GetCount() const
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
int GetUnit() const
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:662
SCH_SCREEN * GetNext()
SCH_SCREEN * GetFirst()
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Definition: sch_screen.cpp:144
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:109
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.
Definition: sch_sheet_pin.h:66
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:57
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:93
VECTOR2I GetPosition() const override
Definition: sch_sheet.h:376
wxString GetShownName(bool aAllowExtraText) const
Definition: sch_sheet.h:103
Schematic symbol object.
Definition: sch_symbol.h:81
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:698
int GetConvert() const
Definition: sch_symbol.h:273
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
Definition: sch_symbol.h:726
bool GetExcludeFromSim() const override
Definition: sch_symbol.cpp:537
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:178
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
Definition: sch_symbol.cpp:939
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:195
VECTOR2I GetPosition() const override
Definition: sch_text.h:212
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.
Definition: reporter.h:164
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:299
The common library.
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.
#define _(s)
const wxString CommentERC_V[]
Definition: erc.cpp:81
const wxString CommentERC_H[]
Definition: erc.cpp:64
const std::set< ELECTRICAL_PINTYPE > DrivenPinTypes
Definition: erc.cpp:119
const std::set< ELECTRICAL_PINTYPE > DrivingPinTypes
Definition: erc.cpp:101
const std::set< ELECTRICAL_PINTYPE > DrivingPowerPinTypes
Definition: erc.cpp:113
@ ERCE_POWERPIN_NOT_DRIVEN
Power input pin connected to some others pins but no power out pin to drive it.
Definition: erc_settings.h:45
@ ERCE_MISSING_POWER_INPUT_PIN
Symbol has power input pins that are not placed on the schematic.
Definition: erc_settings.h:54
@ ERCE_SIMILAR_LABELS
2 labels are equal for case insensitive comparisons.
Definition: erc_settings.h:51
@ ERCE_ENDPOINT_OFF_GRID
Pin or wire-end off grid.
Definition: erc_settings.h:41
@ ERCE_DIFFERENT_UNIT_NET
Shared pin in a multi-unit symbol is connected to more than one net.
Definition: erc_settings.h:58
@ ERCE_UNRESOLVED_VARIABLE
A text variable could not be resolved.
Definition: erc_settings.h:70
@ ERCE_SIMULATION_MODEL
An error was found in the simulation model.
Definition: erc_settings.h:71
@ ERCE_DIFFERENT_UNIT_FP
Different units of the same symbol have different footprints assigned.
Definition: erc_settings.h:52
@ ERCE_NOCONNECT_CONNECTED
A no connect symbol is connected to more than 1 pin.
Definition: erc_settings.h:48
@ ERCE_PIN_TO_PIN_WARNING
Definition: erc_settings.h:85
@ ERCE_PIN_NOT_DRIVEN
Pin connected to some others pins but no pin to drive it.
Definition: erc_settings.h:43
@ ERCE_MISSING_INPUT_PIN
Symbol has input pins that are not placed.
Definition: erc_settings.h:55
@ ERCE_MISSING_UNIT
Symbol has units that are not placed on the schematic.
Definition: erc_settings.h:57
@ ERCE_DUPLICATE_SHEET_NAME
Duplicate sheet names within a given sheet.
Definition: erc_settings.h:40
@ ERCE_MISSING_BIDI_PIN
Symbol has bi-directional pins that are not placed.
Definition: erc_settings.h:56
@ ERCE_LIB_SYMBOL_ISSUES
Library symbol changed from current symbol in schematic or the library symbol link no longer valid.
Definition: erc_settings.h:73
@ ERCE_BUS_ALIAS_CONFLICT
Conflicting bus alias definitions across sheets.
Definition: erc_settings.h:60
@ ERCE_PIN_TO_PIN_ERROR
Definition: erc_settings.h:86
PIN_ERROR
The values a pin-to-pin entry in the pin matrix can take on.
Definition: erc_settings.h:93
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
Definition: lib_item.h:54
wxString ElectricalPinTypeGetText(ELECTRICAL_PINTYPE aType)
Definition: pin_type.cpp:239
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
Definition: pin_type.h:36
@ PT_INPUT
usual pin input: must be connected
@ PT_OUTPUT
usual output
@ 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)
const double IU_PER_MILS
Definition: base_units.h:78
constexpr int MilsToIU(int mils) const
Definition: base_units.h:94
@ SCH_LINE_T
Definition: typeinfo.h:136
@ SCH_SYMBOL_T
Definition: typeinfo.h:146
@ SCH_LABEL_T
Definition: typeinfo.h:141
@ SCH_LOCATE_ANY_T
Definition: typeinfo.h:173
@ SCH_SHEET_T
Definition: typeinfo.h:148
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:143
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:142
@ SCH_PIN_T
Definition: typeinfo.h:149
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588