KiCad PCB EDA Suite
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-2022 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 <string_utils.h>
33#include <lib_pin.h>
34#include <sch_edit_frame.h>
35#include <sch_marker.h>
36#include <sch_reference_list.h>
37#include <sch_sheet.h>
38#include <sch_sheet_pin.h>
39#include <sch_textbox.h>
40#include <sch_line.h>
41#include <sch_pin.h>
42#include <schematic.h>
45#include <wx/ffile.h>
46
47#include "sim/sim_model.h"
48
49
50/* ERC tests :
51 * 1 - conflicts between connected pins ( example: 2 connected outputs )
52 * 2 - minimal connections requirements ( 1 input *must* be connected to an
53 * output, or a passive pin )
54 */
55
56/*
57 * Minimal ERC requirements:
58 * All pins *must* be connected (except ELECTRICAL_PINTYPE::PT_NC).
59 * When a pin is not connected in schematic, the user must place a "non
60 * connected" symbol to this pin.
61 * This ensures a forgotten connection will be detected.
62 */
63
64// Messages for matrix rows:
65const wxString CommentERC_H[] =
66{
67 _( "Input Pin" ),
68 _( "Output Pin" ),
69 _( "Bidirectional Pin" ),
70 _( "Tri-State Pin" ),
71 _( "Passive Pin" ),
72 _( "Free Pin" ),
73 _( "Unspecified Pin" ),
74 _( "Power Input Pin" ),
75 _( "Power Output Pin" ),
76 _( "Open Collector" ),
77 _( "Open Emitter" ),
78 _( "No Connection" )
79};
80
81// Messages for matrix columns
82const wxString CommentERC_V[] =
83{
84 _( "Input Pin" ),
85 _( "Output Pin" ),
86 _( "Bidirectional Pin" ),
87 _( "Tri-State Pin" ),
88 _( "Passive Pin" ),
89 _( "Free Pin" ),
90 _( "Unspecified Pin" ),
91 _( "Power Input Pin" ),
92 _( "Power Output Pin" ),
93 _( "Open Collector" ),
94 _( "Open Emitter" ),
95 _( "No Connection" )
96};
97
98
99// List of pin types that are considered drivers for usual input pins
100// i.e. pin type = ELECTRICAL_PINTYPE::PT_INPUT, but not PT_POWER_IN
101// that need only a PT_POWER_OUT pin type to be driven
102const std::set<ELECTRICAL_PINTYPE> DrivingPinTypes =
103 {
109 };
110
111// List of pin types that are considered drivers for power pins
112// In fact only a ELECTRICAL_PINTYPE::PT_POWER_OUT pin type can drive
113// power input pins
114const std::set<ELECTRICAL_PINTYPE> DrivingPowerPinTypes =
115 {
117 };
118
119// List of pin types that require a driver elsewhere on the net
120const std::set<ELECTRICAL_PINTYPE> DrivenPinTypes =
121 {
124 };
125
126int ERC_TESTER::TestDuplicateSheetNames( bool aCreateMarker )
127{
128 SCH_SCREEN* screen;
129 int err_count = 0;
130
131 SCH_SCREENS screenList( m_schematic->Root() );
132
133 for( screen = screenList.GetFirst(); screen != nullptr; screen = screenList.GetNext() )
134 {
135 std::vector<SCH_SHEET*> list;
136
137 for( SCH_ITEM* item : screen->Items().OfType( SCH_SHEET_T ) )
138 list.push_back( static_cast<SCH_SHEET*>( item ) );
139
140 for( size_t i = 0; i < list.size(); i++ )
141 {
142 SCH_SHEET* sheet = list[i];
143
144 for( size_t j = i + 1; j < list.size(); j++ )
145 {
146 SCH_SHEET* test_item = list[j];
147
148 // We have found a second sheet: compare names
149 // we are using case insensitive comparison to avoid mistakes between
150 // similar names like Mysheet and mysheet
151 if( sheet->GetName().CmpNoCase( test_item->GetName() ) == 0 )
152 {
153 if( aCreateMarker )
154 {
155 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_DUPLICATE_SHEET_NAME );
156 ercItem->SetItems( sheet, test_item );
157
158 SCH_MARKER* marker = new SCH_MARKER( ercItem, sheet->GetPosition() );
159 screen->Append( marker );
160 }
161
162 err_count++;
163 }
164 }
165 }
166 }
167
168 return err_count;
169}
170
171
173{
174 DS_DRAW_ITEM_LIST wsItems;
175
176 auto unresolved = [this]( wxString str )
177 {
178 str = ExpandEnvVarSubstitutions( str, &m_schematic->Prj() );
179 return str.Matches( wxT( "*${*}*" ) );
180 };
181
182 if( aDrawingSheet )
183 {
185 wsItems.SetPageNumber( "1" );
186 wsItems.SetSheetCount( 1 );
187 wsItems.SetFileName( "dummyFilename" );
188 wsItems.SetSheetName( "dummySheet" );
189 wsItems.SetSheetLayer( "dummyLayer" );
190 wsItems.SetProject( &m_schematic->Prj() );
191 wsItems.BuildDrawItemsList( aDrawingSheet->GetPageInfo(), aDrawingSheet->GetTitleBlock());
192 }
193
194 SCH_SHEET_PATH savedCurrentSheet = m_schematic->CurrentSheet();
196
197 for( SCH_SHEET_PATH& sheet : sheets )
198 {
200 SCH_SCREEN* screen = sheet.LastScreen();
201
202 for( SCH_ITEM* item : screen->Items().OfType( SCH_LOCATE_ANY_T ) )
203 {
204 if( item->Type() == SCH_SYMBOL_T )
205 {
206 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
207
208 for( SCH_FIELD& field : symbol->GetFields() )
209 {
210 if( unresolved( field.GetShownText() ) )
211 {
212 VECTOR2I pos = field.GetPosition() - symbol->GetPosition();
213 pos = symbol->GetTransform().TransformCoordinate( pos );
214 pos += symbol->GetPosition();
215
216 std::shared_ptr<ERC_ITEM> ercItem =
218 ercItem->SetItems( &field );
219
220 SCH_MARKER* marker = new SCH_MARKER( ercItem, pos );
221 screen->Append( marker );
222 }
223 }
224 }
225 else if( item->Type() == SCH_SHEET_T )
226 {
227 SCH_SHEET* subSheet = static_cast<SCH_SHEET*>( item );
228
229 for( SCH_FIELD& field : subSheet->GetFields() )
230 {
231 if( unresolved( field.GetShownText() ) )
232 {
233 std::shared_ptr<ERC_ITEM> ercItem =
235 ercItem->SetItems( &field );
236
237 SCH_MARKER* marker = new SCH_MARKER( ercItem, field.GetPosition() );
238 screen->Append( marker );
239 }
240 }
241
242 for( SCH_SHEET_PIN* pin : static_cast<SCH_SHEET*>( item )->GetPins() )
243 {
244 if( pin->GetShownText().Matches( wxT( "*${*}*" ) ) )
245 {
246 std::shared_ptr<ERC_ITEM> ercItem =
248 ercItem->SetItems( pin );
249
250 SCH_MARKER* marker = new SCH_MARKER( ercItem, pin->GetPosition() );
251 screen->Append( marker );
252 }
253 }
254 }
255 else if( SCH_TEXT* text = dynamic_cast<SCH_TEXT*>( item ) )
256 {
257 if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
258 {
259 std::shared_ptr<ERC_ITEM> ercItem =
261 ercItem->SetItems( text );
262
263 SCH_MARKER* marker = new SCH_MARKER( ercItem, text->GetPosition() );
264 screen->Append( marker );
265 }
266 }
267 else if( SCH_TEXTBOX* textBox = dynamic_cast<SCH_TEXTBOX*>( item ) )
268 {
269 if( textBox->GetShownText().Matches( wxT( "*${*}*" ) ) )
270 {
271 std::shared_ptr<ERC_ITEM> ercItem =
273 ercItem->SetItems( textBox );
274
275 SCH_MARKER* marker = new SCH_MARKER( ercItem, textBox->GetPosition() );
276 screen->Append( marker );
277 }
278 }
279 }
280
281 for( DS_DRAW_ITEM_BASE* item = wsItems.GetFirst(); item; item = wsItems.GetNext() )
282 {
283 if( DS_DRAW_ITEM_TEXT* text = dynamic_cast<DS_DRAW_ITEM_TEXT*>( item ) )
284 {
285 if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
286 {
287 std::shared_ptr<ERC_ITEM> erc = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
288 erc->SetErrorMessage( _( "Unresolved text variable in drawing sheet" ) );
289
290 SCH_MARKER* marker = new SCH_MARKER( erc, text->GetPosition() );
291 screen->Append( marker );
292 }
293 }
294 }
295 }
296
297 m_schematic->SetCurrentSheet( savedCurrentSheet );
298}
299
300
302{
303 wxString msg;
304 int err_count = 0;
305
306 SCH_SCREENS screens( m_schematic->Root() );
307 std::vector< std::shared_ptr<BUS_ALIAS> > aliases;
308
309 for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
310 {
311 const std::set< std::shared_ptr<BUS_ALIAS> > screen_aliases = screen->GetBusAliases();
312
313 for( const std::shared_ptr<BUS_ALIAS>& alias : screen_aliases )
314 {
315 std::vector<wxString> aliasMembers = alias->Members();
316 std::sort( aliasMembers.begin(), aliasMembers.end() );
317
318 for( const std::shared_ptr<BUS_ALIAS>& test : aliases )
319 {
320 std::vector<wxString> testMembers = test->Members();
321 std::sort( testMembers.begin(), testMembers.end() );
322
323 if( alias->GetName() == test->GetName() && aliasMembers != testMembers )
324 {
325 msg.Printf( _( "Bus alias %s has conflicting definitions on %s and %s" ),
326 alias->GetName(),
327 alias->GetParent()->GetFileName(),
328 test->GetParent()->GetFileName() );
329
330 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_BUS_ALIAS_CONFLICT );
331 ercItem->SetErrorMessage( msg );
332
333 SCH_MARKER* marker = new SCH_MARKER( ercItem, wxPoint() );
334 test->GetParent()->Append( marker );
335
336 ++err_count;
337 }
338 }
339 }
340
341 aliases.insert( aliases.end(), screen_aliases.begin(), screen_aliases.end() );
342 }
343
344 return err_count;
345}
346
347
349{
351
352 int errors = 0;
354 sheets.GetMultiUnitSymbols( refMap, true );
355
356 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : refMap )
357 {
358 SCH_REFERENCE_LIST& refList = symbol.second;
359
360 if( refList.GetCount() == 0 )
361 {
362 wxFAIL; // it should not happen
363 continue;
364 }
365
366 // Reference footprint
367 SCH_SYMBOL* unit = nullptr;
368 wxString unitName;
369 wxString unitFP;
370
371 for( unsigned i = 0; i < refList.GetCount(); ++i )
372 {
373 SCH_SHEET_PATH sheetPath = refList.GetItem( i ).GetSheetPath();
374 unitFP = refList.GetItem( i ).GetFootprint();
375
376 if( !unitFP.IsEmpty() )
377 {
378 unit = refList.GetItem( i ).GetSymbol();
379 unitName = unit->GetRef( &sheetPath, true );
380 break;
381 }
382 }
383
384 for( unsigned i = 0; i < refList.GetCount(); ++i )
385 {
386 SCH_REFERENCE& secondRef = refList.GetItem( i );
387 SCH_SYMBOL* secondUnit = secondRef.GetSymbol();
388 wxString secondName = secondUnit->GetRef( &secondRef.GetSheetPath(), true );
389 const wxString secondFp = secondRef.GetFootprint();
390 wxString msg;
391
392 if( unit && !secondFp.IsEmpty() && unitFP != secondFp )
393 {
394 msg.Printf( _( "Different footprints assigned to %s and %s" ),
395 unitName, secondName );
396
397 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_DIFFERENT_UNIT_FP );
398 ercItem->SetErrorMessage( msg );
399 ercItem->SetItems( unit, secondUnit );
400
401 SCH_MARKER* marker = new SCH_MARKER( ercItem, secondUnit->GetPosition() );
402 secondRef.GetSheetPath().LastScreen()->Append( marker );
403
404 ++errors;
405 }
406 }
407 }
408
409 return errors;
410}
411
412
414{
415 ERC_SETTINGS& settings = m_schematic->ErcSettings();
417
418 int errors = 0;
420 sheets.GetMultiUnitSymbols( refMap, true );
421
422 for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : refMap )
423 {
424 SCH_REFERENCE_LIST& refList = symbol.second;
425
426 wxCHECK2( refList.GetCount(), continue );
427
428 // Reference unit
429 SCH_REFERENCE& base_ref = refList.GetItem( 0 );
430 SCH_SYMBOL* unit = base_ref.GetSymbol();
431 LIB_SYMBOL* libSymbol = base_ref.GetLibPart();
432
433 if( static_cast<ssize_t>( refList.GetCount() ) == libSymbol->GetUnitCount() )
434 continue;
435
436 std::set<int> lib_units;
437 std::set<int> instance_units;
438 std::set<int> missing_units;
439
440 auto report_missing = [&]( std::set<int>& aMissingUnits, wxString aErrorMsg, int aErrorCode )
441 {
442 wxString msg;
443 wxString missing_pin_units = wxT( "[ " );
444 int ii = 0;
445
446 for( int missing_unit : aMissingUnits )
447 {
448 if( ii++ == 3 )
449 {
450 missing_pin_units += wxT( "....." );
451 break;
452 }
453
454 missing_pin_units += libSymbol->GetUnitDisplayName( missing_unit ) + ", " ;
455 }
456
457 missing_pin_units.Truncate( missing_pin_units.length() - 2 );
458 missing_pin_units += wxT( " ]" );
459
460 msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
461
462 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( aErrorCode );
463 ercItem->SetErrorMessage( msg );
464 ercItem->SetItems( unit );
465
466 SCH_MARKER* marker = new SCH_MARKER( ercItem, unit->GetPosition() );
467 base_ref.GetSheetPath().LastScreen()->Append( marker );
468
469 ++errors;
470 };
471
472 for( int ii = 1; ii <= libSymbol->GetUnitCount(); ++ii )
473 lib_units.insert( lib_units.end(), ii );
474
475 for( size_t ii = 0; ii < refList.GetCount(); ++ii )
476 instance_units.insert( instance_units.end(), refList.GetItem( ii ).GetUnit() );
477
478 std::set_difference( lib_units.begin(), lib_units.end(),
479 instance_units.begin(), instance_units.end(),
480 std::inserter( missing_units, missing_units.begin() ) );
481
482 if( !missing_units.empty() && settings.IsTestEnabled( ERCE_MISSING_UNIT ) )
483 {
484 report_missing( missing_units, _( "Symbol %s has unplaced units %s" ),
486 }
487
488 std::set<int> missing_power;
489 std::set<int> missing_input;
490 std::set<int> missing_bidi;
491
492 for( int missing_unit : missing_units )
493 {
494 LIB_PINS pins;
495 int convert = 0;
496
497 for( size_t ii = 0; ii < refList.GetCount(); ++ii )
498 {
499 if( refList.GetItem( ii ).GetUnit() == missing_unit )
500 {
501 convert = refList.GetItem( ii ).GetSymbol()->GetConvert();
502 break;
503 }
504 }
505
506 libSymbol->GetPins( pins, missing_unit, convert );
507
508 for( auto pin : pins )
509 {
510 switch( pin->GetType() )
511 {
513 missing_power.insert( missing_unit );
514 break;
515
517 missing_bidi.insert( missing_unit );
518 break;
519
521 missing_input.insert( missing_unit );
522 break;
523
524 default:
525 break;
526 }
527 }
528 }
529
530 if( !missing_power.empty() && settings.IsTestEnabled( ERCE_MISSING_POWER_INPUT_PIN ) )
531 {
532 report_missing( missing_power, _( "Symbol %s has input power pins in units %s that are not placed." ),
534 }
535
536 if( !missing_input.empty() && settings.IsTestEnabled( ERCE_MISSING_INPUT_PIN ) )
537 {
538 report_missing( missing_input, _( "Symbol %s has input pins in units %s that are not placed." ),
540 }
541
542 if( !missing_bidi.empty() && settings.IsTestEnabled( ERCE_MISSING_BIDI_PIN ) )
543 {
544 report_missing( missing_bidi, _( "Symbol %s has bidirectional pins in units %s that are not placed." ),
546 }
547 }
548
549 return errors;
550}
551
552
554{
555 int err_count = 0;
556
557 for( const SCH_SHEET_PATH& sheet : m_schematic->GetSheets() )
558 {
559 std::map<VECTOR2I, std::vector<SCH_PIN*>> pinMap;
560
561 for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
562 {
563 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
564
565 for( SCH_PIN* pin : symbol->GetPins( &sheet ) )
566 {
567 if( pin->GetLibPin()->GetType() == ELECTRICAL_PINTYPE::PT_NC )
568 pinMap[pin->GetPosition()].emplace_back( pin );
569 }
570 }
571
572 for( const std::pair<const VECTOR2I, std::vector<SCH_PIN*>>& pair : pinMap )
573 {
574 if( pair.second.size() > 1 )
575 {
576 err_count++;
577
578 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_NOCONNECT_CONNECTED );
579
580 ercItem->SetItems( pair.second[0], pair.second[1],
581 pair.second.size() > 2 ? pair.second[2] : nullptr,
582 pair.second.size() > 3 ? pair.second[3] : nullptr );
583 ercItem->SetErrorMessage( _( "Pins with 'no connection' type are connected" ) );
584
585 SCH_MARKER* marker = new SCH_MARKER( ercItem, pair.first );
586 sheet.LastScreen()->Append( marker );
587 }
588 }
589 }
590
591 return err_count;
592}
593
594
596{
597 ERC_SETTINGS& settings = m_schematic->ErcSettings();
598 const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
599
600 int errors = 0;
601
602 for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
603 {
604 std::vector<SCH_PIN*> pins;
605 std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
606 bool has_noconnect = false;
607
608 for( CONNECTION_SUBGRAPH* subgraph: net.second )
609 {
610 if( subgraph->m_no_connect )
611 has_noconnect = true;
612
613 for( EDA_ITEM* item : subgraph->m_items )
614 {
615 if( item->Type() == SCH_PIN_T )
616 {
617 pins.emplace_back( static_cast<SCH_PIN*>( item ) );
618 pinToScreenMap[item] = subgraph->m_sheet.LastScreen();
619 }
620 }
621 }
622
623 std::set<std::pair<SCH_PIN*, SCH_PIN*>> tested;
624
625 SCH_PIN* needsDriver = nullptr;
626 bool hasDriver = false;
627
628 // We need different drivers for power nets and normal nets.
629 // A power net has at least one pin having the ELECTRICAL_PINTYPE::PT_POWER_IN
630 // and power nets can be driven only by ELECTRICAL_PINTYPE::PT_POWER_OUT pins
631 bool ispowerNet = false;
632
633 for( SCH_PIN* refPin : pins )
634 {
635 if( refPin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
636 {
637 ispowerNet = true;
638 break;
639 }
640 }
641
642 for( SCH_PIN* refPin : pins )
643 {
644 ELECTRICAL_PINTYPE refType = refPin->GetType();
645
646 if( DrivenPinTypes.count( refType ) )
647 {
648 // needsDriver will be the pin shown in the error report eventually, so try to
649 // upgrade to a "better" pin if possible: something visible and only a power symbol
650 // if this net needs a power driver
651 if( !needsDriver ||
652 ( !needsDriver->IsVisible() && refPin->IsVisible() ) ||
653 ( ispowerNet != ( needsDriver->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN ) &&
654 ispowerNet == ( refType == ELECTRICAL_PINTYPE::PT_POWER_IN ) ) )
655 {
656 needsDriver = refPin;
657 }
658 }
659
660 if( ispowerNet )
661 hasDriver |= ( DrivingPowerPinTypes.count( refType ) != 0 );
662 else
663 hasDriver |= ( DrivingPinTypes.count( refType ) != 0 );
664
665 for( SCH_PIN* testPin : pins )
666 {
667 if( testPin == refPin )
668 continue;
669
670 SCH_PIN* first_pin = refPin;
671 SCH_PIN* second_pin = testPin;
672
673 if( first_pin > second_pin )
674 std::swap( first_pin, second_pin );
675
676 std::pair<SCH_PIN*, SCH_PIN*> pair = std::make_pair( first_pin, second_pin );
677
678 if( auto [ins_pin, inserted ] = tested.insert( pair ); !inserted )
679 continue;
680
681 // Multiple pins in the same symbol that share a type,
682 // name and position are considered
683 // "stacked" and shouldn't trigger ERC errors
684 if( refPin->GetParent() == testPin->GetParent() &&
685 refPin->GetPosition() == testPin->GetPosition() &&
686 refPin->GetName() == testPin->GetName() &&
687 refPin->GetType() == testPin->GetType() )
688 continue;
689
690 ELECTRICAL_PINTYPE testType = testPin->GetType();
691
692 if( ispowerNet )
693 hasDriver |= ( DrivingPowerPinTypes.count( testType ) != 0 );
694 else
695 hasDriver |= ( DrivingPinTypes.count( testType ) != 0 );
696
697 PIN_ERROR erc = settings.GetPinMapValue( refType, testType );
698
700 {
701 std::shared_ptr<ERC_ITEM> ercItem =
704 ercItem->SetItems( refPin, testPin );
705 ercItem->SetIsSheetSpecific();
706
707 ercItem->SetErrorMessage(
708 wxString::Format( _( "Pins of type %s and %s are connected" ),
709 ElectricalPinTypeGetText( refType ),
710 ElectricalPinTypeGetText( testType ) ) );
711
712 SCH_MARKER* marker = new SCH_MARKER( ercItem,
713 refPin->GetTransformedPosition() );
714 pinToScreenMap[refPin]->Append( marker );
715 errors++;
716 }
717 }
718 }
719
720 if( needsDriver && !hasDriver && !has_noconnect )
721 {
722 int err_code = ispowerNet ? ERCE_POWERPIN_NOT_DRIVEN : ERCE_PIN_NOT_DRIVEN;
723
724 if( settings.IsTestEnabled( err_code ) )
725 {
726 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( err_code );
727
728 ercItem->SetItems( needsDriver );
729
730 SCH_MARKER* marker = new SCH_MARKER( ercItem,
731 needsDriver->GetTransformedPosition() );
732 pinToScreenMap[needsDriver]->Append( marker );
733 errors++;
734 }
735 }
736 }
737
738 return errors;
739}
740
741
743{
744 const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
745
746 int errors = 0;
747
748 std::unordered_map<wxString, std::pair<wxString, SCH_PIN*>> pinToNetMap;
749
750 for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
751 {
752 const wxString& netName = net.first.Name;
753
754 for( CONNECTION_SUBGRAPH* subgraph : net.second )
755 {
756 for( EDA_ITEM* item : subgraph->m_items )
757 {
758 if( item->Type() == SCH_PIN_T )
759 {
760 SCH_PIN* pin = static_cast<SCH_PIN*>( item );
761
762 if( !pin->GetLibPin()->GetParent()->IsMulti() )
763 continue;
764
765 wxString name = pin->GetParentSymbol()->GetRef( &subgraph->m_sheet ) +
766 + ":" + pin->GetShownNumber();
767
768 if( !pinToNetMap.count( name ) )
769 {
770 pinToNetMap[name] = std::make_pair( netName, pin );
771 }
772 else if( pinToNetMap[name].first != netName )
773 {
774 std::shared_ptr<ERC_ITEM> ercItem =
776
777 ercItem->SetErrorMessage( wxString::Format(
778 _( "Pin %s is connected to both %s and %s" ),
779 pin->GetShownNumber(),
780 netName,
781 pinToNetMap[name].first ) );
782
783 ercItem->SetItems( pin, pinToNetMap[name].second );
784 ercItem->SetIsSheetSpecific();
785
786 SCH_MARKER* marker = new SCH_MARKER( ercItem,
787 pin->GetTransformedPosition() );
788 subgraph->m_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, SCH_LABEL_BASE*> 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( EDA_ITEM* item : subgraph->m_items )
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().Lower();
823
824 if( !labelMap.count( normalized ) )
825 {
826 labelMap[normalized] = label;
827 }
828 else if( labelMap.at( normalized )->GetShownText() != label->GetShownText() )
829 {
830 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_SIMILAR_LABELS );
831 ercItem->SetItems( label, labelMap.at( normalized ) );
832
833 SCH_MARKER* marker = new SCH_MARKER( ercItem, label->GetPosition() );
834 subgraph->m_sheet.LastScreen()->Append( marker );
835 errors += 1;
836 }
837
838 break;
839 }
840
841 default:
842 break;
843 }
844 }
845 }
846 }
847
848 return errors;
849}
850
851
853{
854 wxCHECK( m_schematic, 0 );
855
856 SYMBOL_LIB_TABLE* libTable = m_schematic->Prj().SchSymbolLibTable();
857 wxString msg;
858 int err_count = 0;
859
860 SCH_SCREENS screens( m_schematic->Root() );
861
862 for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
863 {
864 std::vector<SCH_MARKER*> markers;
865
866 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
867 {
868 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
869 LIB_SYMBOL* libSymbolInSchematic = symbol->GetLibSymbolRef().get();
870
871 wxCHECK2( libSymbolInSchematic, continue );
872
873 wxString libName = symbol->GetLibId().GetLibNickname();
874 LIB_TABLE_ROW* libTableRow = libTable->FindRow( libName, true );
875
876 if( !libTableRow )
877 {
878 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LIB_SYMBOL_ISSUES );
879 ercItem->SetItems( symbol );
880 msg.Printf( _( "The current configuration does not include the library '%s'" ),
881 UnescapeString( libName ) );
882 ercItem->SetErrorMessage( msg );
883
884 markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
885 continue;
886 }
887 else if( !libTable->HasLibrary( libName, true ) )
888 {
889 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LIB_SYMBOL_ISSUES );
890 ercItem->SetItems( symbol );
891 msg.Printf( _( "The library '%s' is not enabled in the current configuration" ),
892 UnescapeString( libName ) );
893 ercItem->SetErrorMessage( msg );
894
895 markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
896 continue;
897 }
898
899 wxString symbolName = symbol->GetLibId().GetLibItemName();
900 LIB_SYMBOL* libSymbol = SchGetLibSymbol( symbol->GetLibId(), libTable );
901
902 if( libSymbol == nullptr )
903 {
904 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LIB_SYMBOL_ISSUES );
905 ercItem->SetItems( symbol );
906 msg.Printf( _( "Symbol '%s' not found in symbol library '%s'" ),
907 UnescapeString( symbolName ),
908 UnescapeString( libName ) );
909 ercItem->SetErrorMessage( msg );
910
911 markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
912 continue;
913 }
914
915 std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
916 constexpr int flags = LIB_ITEM::COMPARE_FLAGS::EQUALITY | LIB_ITEM::COMPARE_FLAGS::ERC;
917
918 if( flattenedSymbol->Compare( *libSymbolInSchematic, flags ) != 0 )
919 {
920 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LIB_SYMBOL_ISSUES );
921 ercItem->SetItems( symbol );
922 msg.Printf( _( "Symbol '%s' has been modified in library '%s'" ),
923 UnescapeString( symbolName ),
924 UnescapeString( libName ) );
925 ercItem->SetErrorMessage( msg );
926
927 markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
928 }
929 }
930
931 for( SCH_MARKER* marker : markers )
932 {
933 screen->Append( marker );
934 err_count += 1;
935 }
936 }
937
938 return err_count;
939}
940
941
943{
944 // The minimal grid size allowed to place a pin is 25 mils
945 // the best grid size is 50 mils, but 25 mils is still usable
946 // this is because all symbols are using a 50 mils grid to place pins, and therefore
947 // the wires must be on the 50 mils grid
948 // So raise an error if a pin is not on a 25 mil (or bigger: 50 mil or 100 mil) grid
949 const int min_grid_size = schIUScale.MilsToIU( 25 );
950 const int clamped_grid_size = ( aGridSize < min_grid_size ) ? min_grid_size : aGridSize;
951
952 SCH_SCREENS screens( m_schematic->Root() );
953 int err_count = 0;
954
955 for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
956 {
957 std::vector<SCH_MARKER*> markers;
958
959 for( SCH_ITEM* item : screen->Items() )
960 {
961 if( item->Type() == SCH_LINE_T && item->IsConnectable() )
962 {
963 SCH_LINE* line = static_cast<SCH_LINE*>( item );
964
965 if( ( line->GetStartPoint().x % clamped_grid_size ) != 0
966 || ( line->GetStartPoint().y % clamped_grid_size) != 0 )
967 {
968 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_ENDPOINT_OFF_GRID );
969 ercItem->SetItems( line );
970
971 markers.emplace_back( new SCH_MARKER( ercItem, line->GetStartPoint() ) );
972 }
973 else if( ( line->GetEndPoint().x % clamped_grid_size ) != 0
974 || ( line->GetEndPoint().y % clamped_grid_size) != 0 )
975 {
976 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_ENDPOINT_OFF_GRID );
977 ercItem->SetItems( line );
978
979 markers.emplace_back( new SCH_MARKER( ercItem, line->GetEndPoint() ) );
980 }
981 }
982 else if( item->Type() == SCH_SYMBOL_T )
983 {
984 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
985
986 for( SCH_PIN* pin : symbol->GetPins( nullptr ) )
987 {
988 VECTOR2I pinPos = pin->GetTransformedPosition();
989
990 if( ( pinPos.x % clamped_grid_size ) != 0
991 || ( pinPos.y % clamped_grid_size) != 0 )
992 {
993 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_ENDPOINT_OFF_GRID );
994 ercItem->SetItems( pin );
995
996 markers.emplace_back( new SCH_MARKER( ercItem, pinPos ) );
997 break;
998 }
999 }
1000 }
1001 }
1002
1003 for( SCH_MARKER* marker : markers )
1004 {
1005 screen->Append( marker );
1006 err_count += 1;
1007 }
1008 }
1009
1010 return err_count;
1011}
1012
1013
1015{
1017 int err_count = 0;
1018
1019 for( SCH_SHEET_PATH& sheet : sheets )
1020 {
1021 std::vector<SCH_MARKER*> markers;
1022
1023 for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
1024 {
1025 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1026
1027 try
1028 {
1029 /* JEY TODO
1030 std::unique_ptr<SIM_MODEL> model = SIM_MODEL::Create( &sheet, symbol, true );
1031 */
1032 }
1033 catch( IO_ERROR& e )
1034 {
1035 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_SIMULATION_MODEL );
1036 ercItem->SetErrorMessage( e.Problem() );
1037 ercItem->SetItems( symbol );
1038
1039 markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
1040 }
1041 }
1042
1043 for( SCH_MARKER* marker : markers )
1044 {
1045 sheet.LastScreen()->Append( marker );
1046 err_count += 1;
1047 }
1048 }
1049
1050 return err_count;
1051}
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.
std::vector< SCH_ITEM * > m_items
SCH_ITEM * m_no_connect
No-connect item in graph, if any.
SCH_SHEET_PATH m_sheet
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:385
DS_DRAW_ITEM_BASE * GetFirst()
Definition: ds_draw_item.h:485
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:429
void SetSheetName(const wxString &aSheetName)
Set the sheet name to draw/plot.
Definition: ds_draw_item.h:434
void SetSheetLayer(const wxString &aSheetLayer)
Set the sheet layer to draw/plot.
Definition: ds_draw_item.h:444
void SetSheetCount(int aSheetCount)
Set the value of the count of sheets, for basic inscriptions.
Definition: ds_draw_item.h:472
void SetPageNumber(const wxString &aPageNumber)
Set the value of the sheet number.
Definition: ds_draw_item.h:462
DS_DRAW_ITEM_BASE * GetNext()
Definition: ds_draw_item.h:495
void SetMilsToIUfactor(double aMils2Iu)
Set the scalar to convert pages units (mils) to draw/plot units.
Definition: ds_draw_item.h:452
void SetProject(const PROJECT *aProject)
Definition: ds_draw_item.h:409
A graphic text.
Definition: ds_draw_item.h:303
const PAGE_INFO & GetPageInfo()
const TITLE_BLOCK & GetTitleBlock()
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
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:227
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:852
void TestTextVars(DS_PROXY_VIEW_ITEM *aDrawingSheet)
Check for any unresolved text variable references.
Definition: erc.cpp:172
int TestPinToPin()
Checks the full netlist against the pin-to-pin connectivity requirements.
Definition: erc.cpp:595
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:126
int TestMultUnitPinConflicts()
Checks if shared pins on multi-unit symbols have been connected to different nets.
Definition: erc.cpp:742
int TestOffGridEndpoints(int aGridSize)
Test pins and wire ends for being off grid.
Definition: erc.cpp:942
int TestConflictingBusAliases()
Check that there are no conflicting bus alias definitions in the schematic.
Definition: erc.cpp:301
int TestNoConnectPins()
In KiCad 5 and earlier, you could connect stuff up to pins with NC electrical type.
Definition: erc.cpp:553
int TestSimModelIssues()
Test SPICE models for various issues.
Definition: erc.cpp:1014
SCHEMATIC * m_schematic
Definition: erc.h:148
int TestMissingUnits()
Test for uninstantiated units of multi unit symbols.
Definition: erc.cpp:413
int TestMultiunitFootprints()
Test if all units of each multiunit symbol have the same footprint assigned.
Definition: erc.cpp:348
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
virtual const wxString Problem() const
what was the problem?
Definition: exceptions.cpp:46
const UTF8 & GetLibItemName() const
Definition: lib_id.h:101
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
Define a library symbol object.
Definition: lib_symbol.h:98
wxString GetUnitDisplayName(int aUnit) override
Return the user-defined display name for aUnit for symbols with units.
Definition: lib_symbol.cpp:403
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:856
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:460
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:120
CONNECTION_GRAPH * ConnectionGraph() const override
Definition: schematic.h:130
void SetCurrentSheet(const SCH_SHEET_PATH &aPath) override
Definition: schematic.h:125
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:86
SCH_SHEET & Root() const
Definition: schematic.h:91
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:76
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:179
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:50
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147
wxString GetShownText(int aDepth=0, bool aAllowExtraText=true) const override
Return the string actually shown after processing of the base text.
Definition: sch_label.cpp:560
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:318
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:608
SCH_SCREEN * GetNext()
SCH_SCREEN * GetFirst()
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:109
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:141
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()
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:55
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:91
wxString GetName() const
Definition: sch_sheet.h:101
VECTOR2I GetPosition() const override
Definition: sch_sheet.h:366
Schematic symbol object.
Definition: sch_symbol.h:80
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:624
int GetConvert() const
Definition: sch_symbol.h:269
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve a list of the SCH_PINs for the given sheet path.
Definition: sch_symbol.cpp:989
VECTOR2I GetPosition() const override
Definition: sch_symbol.h:697
TRANSFORM & GetTransform()
Definition: sch_symbol.h:277
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:174
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
Definition: sch_symbol.cpp:824
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:191
VECTOR2I GetPosition() const override
Definition: sch_text.h:203
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...
VECTOR2I TransformCoordinate(const VECTOR2I &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition: transform.cpp:41
const wxString ExpandEnvVarSubstitutions(const wxString &aString, PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:267
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:82
const wxString CommentERC_H[]
Definition: erc.cpp:65
const std::set< ELECTRICAL_PINTYPE > DrivenPinTypes
Definition: erc.cpp:120
const std::set< ELECTRICAL_PINTYPE > DrivingPinTypes
Definition: erc.cpp:102
const std::set< ELECTRICAL_PINTYPE > DrivingPowerPinTypes
Definition: erc.cpp:114
@ 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:240
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_NC
not connected (must be left open)
@ 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
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
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:146
@ SCH_SYMBOL_T
Definition: typeinfo.h:156
@ SCH_LABEL_T
Definition: typeinfo.h:151
@ SCH_LOCATE_ANY_T
Definition: typeinfo.h:183
@ SCH_SHEET_T
Definition: typeinfo.h:158
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:153
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:152
@ SCH_PIN_T
Definition: typeinfo.h:159