KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_nc_pin_connectivity.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 The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 3
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * https://www.gnu.org/licenses/gpl-3.0.en.html
19 * or you may search the http://www.gnu.org website for the version 32 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
26
27#include <connection_graph.h>
28#include <schematic.h>
29#include <sch_sheet.h>
30#include <sch_screen.h>
32#include <lib_symbol.h>
33#include <sch_pin.h>
34#include <sch_symbol.h>
35#include <erc/erc_settings.h>
36#include <erc/erc.h>
37#include <erc/erc_report.h>
38
40{
42 {
43 m_settingsManager.LoadProject( "" );
44 m_schematic = std::make_unique<SCHEMATIC>( &m_settingsManager.Prj() );
45 m_schematic->Reset();
46
47 SCH_SHEET* root = new SCH_SHEET( m_schematic.get() );
48 m_schematic->SetRoot( root );
49 SCH_SCREEN* screen = new SCH_SCREEN( m_schematic.get() );
50 root->SetScreen( screen );
51 }
52
54 std::unique_ptr<SCHEMATIC> m_schematic;
55};
56
58{
59 SCH_SCREEN* screen = m_schematic->RootScreen();
61 path.push_back( &m_schematic->Root() );
62
63 // Create first symbol with NC pin
64 LIB_SYMBOL* libSym1 = new LIB_SYMBOL( "sym1", nullptr );
65 SCH_PIN* libPin1 = new SCH_PIN( libSym1 );
66 libPin1->SetNumber( "1" );
68 libPin1->SetPosition( VECTOR2I( 0, 0 ) );
69 libSym1->AddDrawItem( libPin1 );
70
71 SCH_SYMBOL* sym1 = new SCH_SYMBOL( *libSym1, libSym1->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
72 sym1->UpdatePins();
73 screen->Append( sym1 );
74
75 // Create second symbol with NC pin at same position
76 LIB_SYMBOL* libSym2 = new LIB_SYMBOL( "sym2", nullptr );
77 SCH_PIN* libPin2 = new SCH_PIN( libSym2 );
78 libPin2->SetNumber( "1" );
80 libPin2->SetPosition( VECTOR2I( 0, 0 ) );
81 libSym2->AddDrawItem( libPin2 );
82
83 SCH_SYMBOL* sym2 = new SCH_SYMBOL( *libSym2, libSym2->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
84 sym2->UpdatePins();
85 screen->Append( sym2 );
86
87 // Recalculate connectivity
88 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
89 m_schematic->ConnectionGraph()->Recalculate( sheets, true );
90
91 path = sheets[0];
92
93 // Check connectivity
94 SCH_PIN* pin1 = sym1->GetPins( &path )[0];
95 SCH_PIN* pin2 = sym2->GetPins( &path )[0];
96
97 // They should NOT be connected
98 bool connected = false;
99 for( SCH_ITEM* item : pin1->ConnectedItems( path ) )
100 {
101 if( item == pin2 )
102 {
103 connected = true;
104 break;
105 }
106 }
107
108 BOOST_CHECK_MESSAGE( !connected, "Stacked NC pins should not be connected" );
109
110 // Check subgraph codes
111 SCH_CONNECTION* conn1 = pin1->Connection( &path );
112 SCH_CONNECTION* conn2 = pin2->Connection( &path );
113
114 BOOST_CHECK( conn1 );
115 BOOST_CHECK( conn2 );
116
117 if( conn1 && conn2 )
118 {
119 BOOST_CHECK_MESSAGE( conn1->SubgraphCode() != conn2->SubgraphCode(), "Stacked NC pins should be in different subgraphs" );
120 }
121
122 delete libSym1;
123 delete libSym2;
124}
125
127{
128 SCH_SCREEN* screen = m_schematic->RootScreen();
130 path.push_back( &m_schematic->Root() );
131
132 // Create NC pin
133 LIB_SYMBOL* libSym1 = new LIB_SYMBOL( "sym1", nullptr );
134 SCH_PIN* libPin1 = new SCH_PIN( libSym1 );
135 libPin1->SetNumber( "1" );
137 libPin1->SetPosition( VECTOR2I( 0, 0 ) );
138 libSym1->AddDrawItem( libPin1 );
139
140 SCH_SYMBOL* sym1 = new SCH_SYMBOL( *libSym1, libSym1->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
141 sym1->UpdatePins();
142 screen->Append( sym1 );
143
144 // Create normal pin at same position
145 LIB_SYMBOL* libSym2 = new LIB_SYMBOL( "sym2", nullptr );
146 SCH_PIN* libPin2 = new SCH_PIN( libSym2 );
147 libPin2->SetNumber( "1" );
149 libPin2->SetPosition( VECTOR2I( 0, 0 ) );
150 libSym2->AddDrawItem( libPin2 );
151
152 SCH_SYMBOL* sym2 = new SCH_SYMBOL( *libSym2, libSym2->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
153 sym2->UpdatePins();
154 screen->Append( sym2 );
155
156 // Recalculate connectivity
157 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
158 m_schematic->ConnectionGraph()->Recalculate( sheets, true );
159
160 path = sheets[0];
161
162 // Check connectivity
163 SCH_PIN* pin1 = sym1->GetPins( &path )[0];
164 SCH_PIN* pin2 = sym2->GetPins( &path )[0];
165
166 SCH_CONNECTION* conn1 = pin1->Connection( &path );
167 SCH_CONNECTION* conn2 = pin2->Connection( &path );
168
169 BOOST_CHECK( conn1 );
170 BOOST_CHECK( conn2 );
171
172 if( conn1 && conn2 )
173 {
174 BOOST_CHECK_MESSAGE( conn1->SubgraphCode() != conn2->SubgraphCode(), "NC pin should not connect to normal pin" );
175 }
176
177 delete libSym1;
178 delete libSym2;
179}
180
182{
183 SCH_SCREEN* screen = m_schematic->RootScreen();
185 path.push_back( &m_schematic->Root() );
186
187 // Create symbol with two stacked NC pins
188 LIB_SYMBOL* libSym1 = new LIB_SYMBOL( "sym1", nullptr );
189
190 SCH_PIN* libPin1 = new SCH_PIN( libSym1 );
191 libPin1->SetNumber( "1" );
193 libPin1->SetPosition( VECTOR2I( 0, 0 ) );
194 libSym1->AddDrawItem( libPin1 );
195
196 SCH_PIN* libPin2 = new SCH_PIN( libSym1 );
197 libPin2->SetNumber( "2" ); // Different number
199 libPin2->SetPosition( VECTOR2I( 0, 0 ) );
200 libSym1->AddDrawItem( libPin2 );
201
202 SCH_SYMBOL* sym1 = new SCH_SYMBOL( *libSym1, libSym1->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
203 sym1->UpdatePins();
204 screen->Append( sym1 );
205
206 // Recalculate connectivity
207 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
208 m_schematic->ConnectionGraph()->Recalculate( sheets, true );
209
210 path = sheets[0];
211
212 // Check connectivity
213 std::vector<SCH_PIN*> pins = sym1->GetPins( &path );
214 SCH_PIN* pin1 = pins[0];
215 SCH_PIN* pin2 = pins[1];
216
217 SCH_CONNECTION* conn1 = pin1->Connection( &path );
218 SCH_CONNECTION* conn2 = pin2->Connection( &path );
219
220 BOOST_CHECK( conn1 );
221 BOOST_CHECK( conn2 );
222
223 if( conn1 && conn2 )
224 {
225 BOOST_CHECK_MESSAGE( conn1->SubgraphCode() != conn2->SubgraphCode(), "Stacked NC pins on same symbol should not be connected" );
226 }
227
228 delete libSym1;
229}
230
232{
233 SCH_SCREEN* screen = m_schematic->RootScreen();
235 path.push_back( &m_schematic->Root() );
236
237 // Create first symbol with NC pin
238 LIB_SYMBOL* libSym1 = new LIB_SYMBOL( "sym1", nullptr );
239 SCH_PIN* libPin1 = new SCH_PIN( libSym1 );
240 libPin1->SetNumber( "1" );
242 libPin1->SetPosition( VECTOR2I( 0, 0 ) );
243 libSym1->AddDrawItem( libPin1 );
244
245 SCH_SYMBOL* sym1 = new SCH_SYMBOL( *libSym1, libSym1->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
246 sym1->UpdatePins();
247 screen->Append( sym1 );
248
249 // Create second symbol with NC pin at same position
250 LIB_SYMBOL* libSym2 = new LIB_SYMBOL( "sym2", nullptr );
251 SCH_PIN* libPin2 = new SCH_PIN( libSym2 );
252 libPin2->SetNumber( "1" );
254 libPin2->SetPosition( VECTOR2I( 0, 0 ) );
255 libSym2->AddDrawItem( libPin2 );
256
257 SCH_SYMBOL* sym2 = new SCH_SYMBOL( *libSym2, libSym2->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
258 sym2->UpdatePins();
259 screen->Append( sym2 );
260
261 // Run ERC
262 ERC_SETTINGS& settings = m_schematic->ErcSettings();
263 SHEETLIST_ERC_ITEMS_PROVIDER errors( m_schematic.get() );
264
265 // Enable all errors
269
270 m_schematic->ConnectionGraph()->Recalculate( m_schematic->BuildSheetListSortedByPageNumbers(), true );
271 m_schematic->ConnectionGraph()->RunERC();
272
273 ERC_TESTER tester( m_schematic.get() );
274 tester.TestPinToPin();
275 tester.TestNoConnectPins();
276
277 // We expect NO errors for stacked NC pins on same symbol
278 BOOST_CHECK_EQUAL( errors.GetCount(), 0 );
279
280 delete libSym1;
281}
282
284{
285 SCH_SCREEN* screen = m_schematic->RootScreen();
287 path.push_back( &m_schematic->Root() );
288
289 // Create symbol with two stacked NC pins
290 LIB_SYMBOL* libSym1 = new LIB_SYMBOL( "sym1", nullptr );
291
292 SCH_PIN* libPin1 = new SCH_PIN( libSym1 );
293 libPin1->SetNumber( "1" );
295 libPin1->SetPosition( VECTOR2I( 0, 0 ) );
296 libSym1->AddDrawItem( libPin1 );
297
298 SCH_PIN* libPin2 = new SCH_PIN( libSym1 );
299 libPin2->SetNumber( "2" ); // Different number
301 libPin2->SetPosition( VECTOR2I( 0, 0 ) );
302 libSym1->AddDrawItem( libPin2 );
303
304 SCH_SYMBOL* sym1 = new SCH_SYMBOL( *libSym1, libSym1->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
305 sym1->UpdatePins();
306 screen->Append( sym1 );
307
308 // Run ERC
309 ERC_SETTINGS& settings = m_schematic->ErcSettings();
310 SHEETLIST_ERC_ITEMS_PROVIDER errors( m_schematic.get() );
311
312 // Enable all errors
316
317 m_schematic->ConnectionGraph()->Recalculate( m_schematic->BuildSheetListSortedByPageNumbers(), true );
318 m_schematic->ConnectionGraph()->RunERC();
319
320 ERC_TESTER tester( m_schematic.get() );
321 tester.TestPinToPin();
322 int ncErrors = tester.TestNoConnectPins();
323
324 // We expect NO errors for stacked NC pins on same symbol
325 BOOST_CHECK_EQUAL( ncErrors, 0 );
326 BOOST_CHECK_EQUAL( errors.GetCount(), 0 );
327
328 delete libSym1;
329}
330
332{
333 SCH_SCREEN* screen = m_schematic->RootScreen();
335 path.push_back( &m_schematic->Root() );
336
337 // Create NC pin
338 LIB_SYMBOL* libSym1 = new LIB_SYMBOL( "sym1", nullptr );
339 SCH_PIN* libPin1 = new SCH_PIN( libSym1 );
340 libPin1->SetNumber( "1" );
342 libPin1->SetPosition( VECTOR2I( 0, 0 ) );
343 libSym1->AddDrawItem( libPin1 );
344
345 SCH_SYMBOL* sym1 = new SCH_SYMBOL( *libSym1, libSym1->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
346 sym1->UpdatePins();
347 screen->Append( sym1 );
348
349 // Create normal pin at same position
350 LIB_SYMBOL* libSym2 = new LIB_SYMBOL( "sym2", nullptr );
351 SCH_PIN* libPin2 = new SCH_PIN( libSym2 );
352 libPin2->SetNumber( "1" );
354 libPin2->SetPosition( VECTOR2I( 0, 0 ) );
355 libSym2->AddDrawItem( libPin2 );
356
357 SCH_SYMBOL* sym2 = new SCH_SYMBOL( *libSym2, libSym2->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
358 sym2->UpdatePins();
359 screen->Append( sym2 );
360
361 // Run ERC
362 ERC_SETTINGS& settings = m_schematic->ErcSettings();
363
364 // Enable all errors
368
369 m_schematic->ConnectionGraph()->Recalculate( m_schematic->BuildSheetListSortedByPageNumbers(), true );
370 m_schematic->ConnectionGraph()->RunERC();
371
372 ERC_TESTER tester( m_schematic.get() );
373 int ncErrors = tester.TestNoConnectPins();
374
375 BOOST_CHECK_EQUAL( ncErrors, 1 );
376}
377
379{
380 std::cout << "Data dir: " << KI_TEST::GetEeschemaTestDataDir() << std::endl;
381 KI_TEST::LoadSchematic( m_settingsManager, "test1243/test1243", m_schematic );
382
383 // Run ERC
384 ERC_SETTINGS& settings = m_schematic->ErcSettings();
385 SHEETLIST_ERC_ITEMS_PROVIDER errors( m_schematic.get() );
386
387 // Enable all errors
391
392 m_schematic->ConnectionGraph()->Recalculate( m_schematic->BuildSheetListSortedByPageNumbers(), true );
393 m_schematic->ConnectionGraph()->RunERC();
394
395 ERC_TESTER tester( m_schematic.get() );
396 int ncErrors = tester.TestNoConnectPins();
397
398 // We expect NO errors
399 BOOST_CHECK_EQUAL( ncErrors, 0 );
400 BOOST_CHECK_EQUAL( errors.GetCount(), 0 );
401}
Container for ERC settings.
std::map< int, SEVERITY > m_ERCSeverities
int TestPinToPin()
Checks the full netlist against the pin-to-pin connectivity requirements.
Definition erc.cpp:913
int TestNoConnectPins()
In KiCad 5 and earlier, you could connect stuff up to pins with NC electrical type.
Definition erc.cpp:822
Define a library symbol object.
Definition lib_symbol.h:83
const LIB_ID & GetLibId() const override
Definition lib_symbol.h:153
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
int SubgraphCode() const
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:167
const SCH_ITEM_VEC & ConnectedItems(const SCH_SHEET_PATH &aPath)
Retrieve the set of items connected to this item on the given sheet.
Definition sch_item.cpp:418
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
Definition sch_item.cpp:352
void SetNumber(const wxString &aNumber)
Definition sch_pin.cpp:642
void SetPosition(const VECTOR2I &aPos) override
Definition sch_pin.h:251
void SetType(ELECTRICAL_PINTYPE aType)
Definition sch_pin.cpp:333
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:47
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Schematic symbol object.
Definition sch_symbol.h:76
void UpdatePins()
Updates the cache of SCH_PIN objects for each pin.
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
An implementation of the RC_ITEM_LIST interface which uses the global SHEETLIST to fulfill the contra...
int GetCount(int aSeverity=-1) const override
@ ERCE_NOCONNECT_CONNECTED
A no connect symbol is connected to more than 1 pin.
@ ERCE_PIN_TO_PIN_WARNING
@ ERCE_PIN_TO_PIN_ERROR
void LoadSchematic(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< SCHEMATIC > &aSchematic)
std::string GetEeschemaTestDataDir()
Get the configured location of Eeschema test data.
@ PT_NC
not connected (must be left open)
Definition pin_type.h:50
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
Definition pin_type.h:43
@ RPT_SEVERITY_ERROR
std::unique_ptr< SCHEMATIC > m_schematic
std::string path
BOOST_FIXTURE_TEST_CASE(StackedNCPins, NC_PIN_CONNECTIVITY_FIXTURE)
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695