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 SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
47
48 SCH_SHEET* root = new SCH_SHEET( m_schematic.get() );
49 SCH_SCREEN* screen = new SCH_SCREEN( m_schematic.get() );
50 root->SetScreen( screen );
51
52 m_schematic->AddTopLevelSheet( root );
53 m_schematic->RemoveTopLevelSheet( defaultSheet );
54 delete defaultSheet;
55 }
56
58 std::unique_ptr<SCHEMATIC> m_schematic;
59};
60
62{
63 SCH_SCREEN* screen = m_schematic->RootScreen();
65 path.push_back( &m_schematic->Root() );
66
67 // Create first symbol with NC pin
68 LIB_SYMBOL* libSym1 = new LIB_SYMBOL( "sym1", nullptr );
69 SCH_PIN* libPin1 = new SCH_PIN( libSym1 );
70 libPin1->SetNumber( "1" );
72 libPin1->SetPosition( VECTOR2I( 0, 0 ) );
73 libSym1->AddDrawItem( libPin1 );
74
75 SCH_SYMBOL* sym1 = new SCH_SYMBOL( *libSym1, libSym1->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
76 sym1->UpdatePins();
77 screen->Append( sym1 );
78
79 // Create second symbol with NC pin at same position
80 LIB_SYMBOL* libSym2 = new LIB_SYMBOL( "sym2", nullptr );
81 SCH_PIN* libPin2 = new SCH_PIN( libSym2 );
82 libPin2->SetNumber( "1" );
84 libPin2->SetPosition( VECTOR2I( 0, 0 ) );
85 libSym2->AddDrawItem( libPin2 );
86
87 SCH_SYMBOL* sym2 = new SCH_SYMBOL( *libSym2, libSym2->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
88 sym2->UpdatePins();
89 screen->Append( sym2 );
90
91 // Recalculate connectivity
92 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
93 m_schematic->ConnectionGraph()->Recalculate( sheets, true );
94
95 path = sheets[0];
96
97 // Check connectivity
98 SCH_PIN* pin1 = sym1->GetPins( &path )[0];
99 SCH_PIN* pin2 = sym2->GetPins( &path )[0];
100
101 // They should NOT be connected
102 bool connected = false;
103 for( SCH_ITEM* item : pin1->ConnectedItems( path ) )
104 {
105 if( item == pin2 )
106 {
107 connected = true;
108 break;
109 }
110 }
111
112 BOOST_CHECK_MESSAGE( !connected, "Stacked NC pins should not be connected" );
113
114 // Check subgraph codes
115 SCH_CONNECTION* conn1 = pin1->Connection( &path );
116 SCH_CONNECTION* conn2 = pin2->Connection( &path );
117
118 BOOST_CHECK( conn1 );
119 BOOST_CHECK( conn2 );
120
121 if( conn1 && conn2 )
122 {
123 BOOST_CHECK_MESSAGE( conn1->SubgraphCode() != conn2->SubgraphCode(), "Stacked NC pins should be in different subgraphs" );
124 }
125
126 delete libSym1;
127 delete libSym2;
128}
129
131{
132 SCH_SCREEN* screen = m_schematic->RootScreen();
134 path.push_back( &m_schematic->Root() );
135
136 // Create NC pin
137 LIB_SYMBOL* libSym1 = new LIB_SYMBOL( "sym1", nullptr );
138 SCH_PIN* libPin1 = new SCH_PIN( libSym1 );
139 libPin1->SetNumber( "1" );
141 libPin1->SetPosition( VECTOR2I( 0, 0 ) );
142 libSym1->AddDrawItem( libPin1 );
143
144 SCH_SYMBOL* sym1 = new SCH_SYMBOL( *libSym1, libSym1->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
145 sym1->UpdatePins();
146 screen->Append( sym1 );
147
148 // Create normal pin at same position
149 LIB_SYMBOL* libSym2 = new LIB_SYMBOL( "sym2", nullptr );
150 SCH_PIN* libPin2 = new SCH_PIN( libSym2 );
151 libPin2->SetNumber( "1" );
153 libPin2->SetPosition( VECTOR2I( 0, 0 ) );
154 libSym2->AddDrawItem( libPin2 );
155
156 SCH_SYMBOL* sym2 = new SCH_SYMBOL( *libSym2, libSym2->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
157 sym2->UpdatePins();
158 screen->Append( sym2 );
159
160 // Recalculate connectivity
161 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
162 m_schematic->ConnectionGraph()->Recalculate( sheets, true );
163
164 path = sheets[0];
165
166 // Check connectivity
167 SCH_PIN* pin1 = sym1->GetPins( &path )[0];
168 SCH_PIN* pin2 = sym2->GetPins( &path )[0];
169
170 SCH_CONNECTION* conn1 = pin1->Connection( &path );
171 SCH_CONNECTION* conn2 = pin2->Connection( &path );
172
173 BOOST_CHECK( conn1 );
174 BOOST_CHECK( conn2 );
175
176 if( conn1 && conn2 )
177 {
178 BOOST_CHECK_MESSAGE( conn1->SubgraphCode() != conn2->SubgraphCode(), "NC pin should not connect to normal pin" );
179 }
180
181 delete libSym1;
182 delete libSym2;
183}
184
186{
187 SCH_SCREEN* screen = m_schematic->RootScreen();
189 path.push_back( &m_schematic->Root() );
190
191 // Create symbol with two stacked NC pins
192 LIB_SYMBOL* libSym1 = new LIB_SYMBOL( "sym1", nullptr );
193
194 SCH_PIN* libPin1 = new SCH_PIN( libSym1 );
195 libPin1->SetNumber( "1" );
197 libPin1->SetPosition( VECTOR2I( 0, 0 ) );
198 libSym1->AddDrawItem( libPin1 );
199
200 SCH_PIN* libPin2 = new SCH_PIN( libSym1 );
201 libPin2->SetNumber( "2" ); // Different number
203 libPin2->SetPosition( VECTOR2I( 0, 0 ) );
204 libSym1->AddDrawItem( libPin2 );
205
206 SCH_SYMBOL* sym1 = new SCH_SYMBOL( *libSym1, libSym1->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
207 sym1->UpdatePins();
208 screen->Append( sym1 );
209
210 // Recalculate connectivity
211 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
212 m_schematic->ConnectionGraph()->Recalculate( sheets, true );
213
214 path = sheets[0];
215
216 // Check connectivity
217 std::vector<SCH_PIN*> pins = sym1->GetPins( &path );
218 SCH_PIN* pin1 = pins[0];
219 SCH_PIN* pin2 = pins[1];
220
221 SCH_CONNECTION* conn1 = pin1->Connection( &path );
222 SCH_CONNECTION* conn2 = pin2->Connection( &path );
223
224 BOOST_CHECK( conn1 );
225 BOOST_CHECK( conn2 );
226
227 if( conn1 && conn2 )
228 {
229 BOOST_CHECK_MESSAGE( conn1->SubgraphCode() != conn2->SubgraphCode(), "Stacked NC pins on same symbol should not be connected" );
230 }
231
232 delete libSym1;
233}
234
236{
237 SCH_SCREEN* screen = m_schematic->RootScreen();
239 path.push_back( &m_schematic->Root() );
240
241 // Create first symbol with NC pin
242 LIB_SYMBOL* libSym1 = new LIB_SYMBOL( "sym1", nullptr );
243 SCH_PIN* libPin1 = new SCH_PIN( libSym1 );
244 libPin1->SetNumber( "1" );
246 libPin1->SetPosition( VECTOR2I( 0, 0 ) );
247 libSym1->AddDrawItem( libPin1 );
248
249 SCH_SYMBOL* sym1 = new SCH_SYMBOL( *libSym1, libSym1->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
250 sym1->UpdatePins();
251 screen->Append( sym1 );
252
253 // Create second symbol with NC pin at same position
254 LIB_SYMBOL* libSym2 = new LIB_SYMBOL( "sym2", nullptr );
255 SCH_PIN* libPin2 = new SCH_PIN( libSym2 );
256 libPin2->SetNumber( "1" );
258 libPin2->SetPosition( VECTOR2I( 0, 0 ) );
259 libSym2->AddDrawItem( libPin2 );
260
261 SCH_SYMBOL* sym2 = new SCH_SYMBOL( *libSym2, libSym2->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
262 sym2->UpdatePins();
263 screen->Append( sym2 );
264
265 // Run ERC
266 ERC_SETTINGS& settings = m_schematic->ErcSettings();
267 SHEETLIST_ERC_ITEMS_PROVIDER errors( m_schematic.get() );
268
269 // Enable all errors
273
274 m_schematic->ConnectionGraph()->Recalculate( m_schematic->BuildSheetListSortedByPageNumbers(), true );
275 m_schematic->ConnectionGraph()->RunERC();
276
277 ERC_TESTER tester( m_schematic.get() );
278 tester.TestPinToPin();
279 tester.TestNoConnectPins();
280
281 // We expect NO errors for stacked NC pins on same symbol
282 BOOST_CHECK_EQUAL( errors.GetCount(), 0 );
283
284 delete libSym1;
285}
286
288{
289 SCH_SCREEN* screen = m_schematic->RootScreen();
291 path.push_back( &m_schematic->Root() );
292
293 // Create symbol with two stacked NC pins
294 LIB_SYMBOL* libSym1 = new LIB_SYMBOL( "sym1", nullptr );
295
296 SCH_PIN* libPin1 = new SCH_PIN( libSym1 );
297 libPin1->SetNumber( "1" );
299 libPin1->SetPosition( VECTOR2I( 0, 0 ) );
300 libSym1->AddDrawItem( libPin1 );
301
302 SCH_PIN* libPin2 = new SCH_PIN( libSym1 );
303 libPin2->SetNumber( "2" ); // Different number
305 libPin2->SetPosition( VECTOR2I( 0, 0 ) );
306 libSym1->AddDrawItem( libPin2 );
307
308 SCH_SYMBOL* sym1 = new SCH_SYMBOL( *libSym1, libSym1->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
309 sym1->UpdatePins();
310 screen->Append( sym1 );
311
312 // Run ERC
313 ERC_SETTINGS& settings = m_schematic->ErcSettings();
314 SHEETLIST_ERC_ITEMS_PROVIDER errors( m_schematic.get() );
315
316 // Enable all errors
320
321 m_schematic->ConnectionGraph()->Recalculate( m_schematic->BuildSheetListSortedByPageNumbers(), true );
322 m_schematic->ConnectionGraph()->RunERC();
323
324 ERC_TESTER tester( m_schematic.get() );
325 tester.TestPinToPin();
326 int ncErrors = tester.TestNoConnectPins();
327
328 // We expect NO errors for stacked NC pins on same symbol
329 BOOST_CHECK_EQUAL( ncErrors, 0 );
330 BOOST_CHECK_EQUAL( errors.GetCount(), 0 );
331
332 delete libSym1;
333}
334
336{
337 SCH_SCREEN* screen = m_schematic->RootScreen();
339 path.push_back( &m_schematic->Root() );
340
341 // Create NC pin
342 LIB_SYMBOL* libSym1 = new LIB_SYMBOL( "sym1", nullptr );
343 SCH_PIN* libPin1 = new SCH_PIN( libSym1 );
344 libPin1->SetNumber( "1" );
346 libPin1->SetPosition( VECTOR2I( 0, 0 ) );
347 libSym1->AddDrawItem( libPin1 );
348
349 SCH_SYMBOL* sym1 = new SCH_SYMBOL( *libSym1, libSym1->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
350 sym1->UpdatePins();
351 screen->Append( sym1 );
352
353 // Create normal pin at same position
354 LIB_SYMBOL* libSym2 = new LIB_SYMBOL( "sym2", nullptr );
355 SCH_PIN* libPin2 = new SCH_PIN( libSym2 );
356 libPin2->SetNumber( "1" );
358 libPin2->SetPosition( VECTOR2I( 0, 0 ) );
359 libSym2->AddDrawItem( libPin2 );
360
361 SCH_SYMBOL* sym2 = new SCH_SYMBOL( *libSym2, libSym2->GetLibId(), &path, 0, 0, VECTOR2I( 100, 100 ) );
362 sym2->UpdatePins();
363 screen->Append( sym2 );
364
365 // Run ERC
366 ERC_SETTINGS& settings = m_schematic->ErcSettings();
367
368 // Enable all errors
372
373 m_schematic->ConnectionGraph()->Recalculate( m_schematic->BuildSheetListSortedByPageNumbers(), true );
374 m_schematic->ConnectionGraph()->RunERC();
375
376 ERC_TESTER tester( m_schematic.get() );
377 int ncErrors = tester.TestNoConnectPins();
378
379 BOOST_CHECK_EQUAL( ncErrors, 1 );
380}
381
383{
384 std::cout << "Data dir: " << KI_TEST::GetEeschemaTestDataDir() << std::endl;
385 KI_TEST::LoadSchematic( m_settingsManager, "test1243/test1243", m_schematic );
386
387 // Run ERC
388 ERC_SETTINGS& settings = m_schematic->ErcSettings();
389 SHEETLIST_ERC_ITEMS_PROVIDER errors( m_schematic.get() );
390
391 // Enable all errors
395
396 m_schematic->ConnectionGraph()->Recalculate( m_schematic->BuildSheetListSortedByPageNumbers(), true );
397 m_schematic->ConnectionGraph()->RunERC();
398
399 ERC_TESTER tester( m_schematic.get() );
400 int ncErrors = tester.TestNoConnectPins();
401
402 // We expect NO errors
403 BOOST_CHECK_EQUAL( ncErrors, 0 );
404 BOOST_CHECK_EQUAL( errors.GetCount(), 0 );
405}
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:532
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:466
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:48
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