KiCad PCB EDA Suite
Loading...
Searching...
No Matches
erc_settings.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) 2020 CERN
5 * @author Jon Evans <[email protected]>
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <erc_item.h>
22#include <erc_settings.h>
23#include <schematic.h>
24#include <sch_marker.h>
25#include <sch_screen.h>
27#include <settings/parameters.h>
28
29
31
32
33
34#define OK PIN_ERROR::OK
35#define ERR PIN_ERROR::PP_ERROR
36#define WAR PIN_ERROR::WARNING
37
42{
43/* I, O, Bi, 3S, Pas, NIC, UnS, PwrI, PwrO, OC, OE, NC */
44/* I */ { OK, OK, OK, OK, OK, OK, WAR, OK, OK, OK, OK, ERR },
45/* O */ { OK, ERR, OK, WAR, OK, OK, WAR, OK, ERR, ERR, ERR, ERR },
46/* Bi */ { OK, OK, OK, OK, OK, OK, WAR, OK, WAR, OK, WAR, ERR },
47/* 3S */ { OK, WAR, OK, OK, OK, OK, WAR, WAR, ERR, WAR, WAR, ERR },
48/*Pas */ { OK, OK, OK, OK, OK, OK, WAR, OK, OK, OK, OK, ERR },
49/*NIC */ { OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, ERR },
50/*UnS */ { WAR, WAR, WAR, WAR, WAR, OK, WAR, WAR, WAR, WAR, WAR, ERR },
51/*PwrI*/ { OK, OK, OK, WAR, OK, OK, WAR, OK, OK, OK, OK, ERR },
52/*PwrO*/ { OK, ERR, WAR, ERR, OK, OK, WAR, OK, ERR, ERR, ERR, ERR },
53/* OC */ { OK, ERR, OK, WAR, OK, OK, WAR, OK, ERR, OK, OK, ERR },
54/* OE */ { OK, ERR, WAR, WAR, OK, OK, WAR, OK, ERR, OK, OK, ERR },
55/* NC */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR }
56};
57
58
70{
71/* I, O, Bi, 3S, Pas, NIC, UnS, PwrI, PwrO, OC, OE, NC */
72/* I */ { NOD, DRV, DRV, DRV, DRV, NOD, DRV, NOD, DRV, DRV, DRV, NPI },
73/* O */ { DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, DRV, DRV, NPI },
74/* Bi */ { DRV, DRV, DRV, DRV, DRV, NOD, DRV, NOD, DRV, DRV, DRV, NPI },
75/* 3S */ { DRV, DRV, DRV, DRV, DRV, NOD, DRV, NOD, DRV, DRV, DRV, NPI },
76/*Pas */ { DRV, DRV, DRV, DRV, DRV, NOD, DRV, NOD, DRV, DRV, DRV, NPI },
77/*NIC */ { NOD, NOD, NOD, NOD, NOD, NOD, NOD, NOD, NOD, NOD, NOD, NPI },
78/*UnS */ { DRV, DRV, DRV, DRV, DRV, NOD, DRV, NOD, DRV, DRV, DRV, NPI },
79/*PwrI*/ { NOD, DRV, NOD, NOD, NOD, NOD, NOD, NOD, DRV, NOD, NOD, NPI },
80/*PwrO*/ { DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, DRV, DRV, NPI },
81/* OC */ { DRV, DRV, DRV, DRV, DRV, NOD, DRV, NOD, DRV, DRV, DRV, NPI },
82/* OE */ { DRV, DRV, DRV, DRV, DRV, NOD, DRV, NOD, DRV, DRV, DRV, NPI },
83/* NC */ { NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI }
84};
85
86
87ERC_SETTINGS::ERC_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
88 NESTED_SETTINGS( "erc", ercSettingsSchemaVersion, aParent, aPath )
89{
91
92 for( int i = ERCE_FIRST; i <= ERCE_LAST; ++i )
94
95 // Error is the default setting so set non-error priorities here.
110
111 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "rule_severities",
112 [&]() -> nlohmann::json
113 {
114 nlohmann::json ret = {};
115
116 for( const RC_ITEM& item : ERC_ITEM::GetItemsWithSeverities() )
117 {
118 wxString name = item.GetSettingsKey();
119 int code = item.GetErrorCode();
120
121 if( name.IsEmpty() || m_ERCSeverities.count( code ) == 0 )
122 continue;
123
124 ret[std::string( name.ToUTF8() )] = SeverityToString( m_ERCSeverities[code] );
125 }
126
127 return ret;
128 },
129 [&]( const nlohmann::json& aJson )
130 {
131 if( !aJson.is_object() )
132 return;
133
134 for( const RC_ITEM& item : ERC_ITEM::GetItemsWithSeverities() )
135 {
136 int code = item.GetErrorCode();
137 wxString name = item.GetSettingsKey();
138
139 std::string key( name.ToUTF8() );
140
141 if( aJson.contains( key ) )
142 m_ERCSeverities[code] = SeverityFromString( aJson[key] );
143 }
144 },
145 {} ) );
146
147 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "erc_exclusions",
148 [&]() -> nlohmann::json
149 {
150 nlohmann::json js = nlohmann::json::array();
151
152 for( const auto& entry : m_ErcExclusions )
153 js.push_back( entry );
154
155 return js;
156 },
157 [&]( const nlohmann::json& aObj )
158 {
159 m_ErcExclusions.clear();
160
161 if( !aObj.is_array() )
162 return;
163
164 for( const nlohmann::json& entry : aObj )
165 {
166 if( entry.empty() )
167 continue;
168
169 m_ErcExclusions.insert( entry.get<wxString>() );
170 }
171 },
172 {} ) );
173
174 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "pin_map",
175 [&]() -> nlohmann::json
176 {
177 nlohmann::json ret = nlohmann::json::array();
178
179 for( int i = 0; i < ELECTRICAL_PINTYPES_TOTAL; i++ )
180 {
181 nlohmann::json inner = nlohmann::json::array();
182
183 for( int j = 0; j < ELECTRICAL_PINTYPES_TOTAL; j++ )
184 inner.push_back( static_cast<int>( GetPinMapValue( i, j ) ) );
185
186 ret.push_back( inner );
187 }
188
189 return ret;
190 },
191 [&]( const nlohmann::json& aJson )
192 {
193 if( !aJson.is_array() || aJson.size() != ELECTRICAL_PINTYPES_TOTAL )
194 return;
195
196 for( size_t i = 0; i < ELECTRICAL_PINTYPES_TOTAL; i++ )
197 {
198 if( i > aJson.size() - 1 )
199 break;
200
201 nlohmann::json inner = aJson[i];
202
203 if( !inner.is_array() || inner.size() != ELECTRICAL_PINTYPES_TOTAL )
204 return;
205
206 for( size_t j = 0; j < ELECTRICAL_PINTYPES_TOTAL; j++ )
207 {
208 if( inner[j].is_number_integer() )
209 {
210 int val = inner[j].get<int>();
211
212 if( val >= 0 && val <= static_cast<int>( PIN_ERROR::UNCONNECTED ) )
213 SetPinMapValue( i, j, static_cast<PIN_ERROR>( val ) );
214 }
215 }
216 }
217 },
218 {} ) );
219}
220
221
223{
224 if( m_parent )
225 {
227 m_parent = nullptr;
228 }
229}
230
231
232SEVERITY ERC_SETTINGS::GetSeverity( int aErrorCode ) const
233{
234 // Special-case pin-to-pin errors:
235 // Ignore-or-not is controlled by ERCE_PIN_TO_PIN_WARNING (for both)
236 // Warning-or-error is controlled by which errorCode it is
237 if( aErrorCode == ERCE_PIN_TO_PIN_ERROR )
238 {
239 wxASSERT( m_ERCSeverities.count( ERCE_PIN_TO_PIN_WARNING ) );
240
242 return RPT_SEVERITY_IGNORE;
243 else
244 return RPT_SEVERITY_ERROR;
245 }
246 else if( aErrorCode == ERCE_PIN_TO_PIN_WARNING )
247 {
248 wxASSERT( m_ERCSeverities.count( ERCE_PIN_TO_PIN_WARNING ) );
249
251 return RPT_SEVERITY_IGNORE;
252 else
254 }
255
256 wxCHECK_MSG( m_ERCSeverities.count( aErrorCode ), RPT_SEVERITY_IGNORE,
257 wxS( "Missing severity from map in ERC_SETTINGS!" ) );
258
259 return m_ERCSeverities.at( aErrorCode );
260}
261
262
263void ERC_SETTINGS::SetSeverity( int aErrorCode, SEVERITY aSeverity )
264{
265 m_ERCSeverities[ aErrorCode ] = aSeverity;
266}
267
268
270{
271 memcpy( m_PinMap, m_defaultPinMap, sizeof( m_PinMap ) );
272}
273
274
275void SHEETLIST_ERC_ITEMS_PROVIDER::visitMarkers( std::function<void( SCH_MARKER* )> aVisitor ) const
276{
277 SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
278
279 std::set<SCH_SCREEN*> seenScreens;
280
281 for( unsigned i = 0; i < sheetList.size(); i++ )
282 {
283 bool firstTime = seenScreens.count( sheetList[i].LastScreen() ) == 0;
284
285 if( firstTime )
286 seenScreens.insert( sheetList[i].LastScreen() );
287
288 for( SCH_ITEM* item : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) )
289 {
290 SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
291
292 if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC )
293 continue;
294
295 std::shared_ptr<const ERC_ITEM> ercItem =
296 std::static_pointer_cast<const ERC_ITEM>( marker->GetRCItem() );
297
298 // Only show sheet-specific markers on the owning sheet
299 if( ercItem->IsSheetSpecific() )
300 {
301 if( ercItem->GetSpecificSheetPath() != sheetList[i] )
302 continue;
303 }
304
305 // Don't show non-specific markers more than once
306 if( !firstTime && !ercItem->IsSheetSpecific() )
307 continue;
308
309 aVisitor( marker );
310 }
311 }
312}
313
314
316{
317 m_severities = aSeverities;
318
319 m_filteredMarkers.clear();
320
321 ERC_SETTINGS& settings = m_schematic->ErcSettings();
322
324 [&]( SCH_MARKER* aMarker )
325 {
326 SEVERITY markerSeverity;
327
328 if( aMarker->IsExcluded() )
329 markerSeverity = RPT_SEVERITY_EXCLUSION;
330 else
331 markerSeverity = settings.GetSeverity( aMarker->GetRCItem()->GetErrorCode() );
332
333 if( markerSeverity & m_severities )
334 m_filteredMarkers.push_back( aMarker );
335 } );
336}
337
338
340{
341 if( aSeverity < 0 )
342 return m_filteredMarkers.size();
343
344 int count = 0;
345
346 const ERC_SETTINGS& settings = m_schematic->ErcSettings();
347
349 [&]( SCH_MARKER* aMarker )
350 {
351 SEVERITY markerSeverity;
352
353 if( aMarker->IsExcluded() )
354 markerSeverity = RPT_SEVERITY_EXCLUSION;
355 else
356 markerSeverity = settings.GetSeverity( aMarker->GetRCItem()->GetErrorCode() );
357
358 if( ( markerSeverity & aSeverity ) > 0 )
359 count++;
360 } );
361
362 return count;
363}
364
365
366std::shared_ptr<ERC_ITEM> SHEETLIST_ERC_ITEMS_PROVIDER::GetERCItem( int aIndex ) const
367{
368 SCH_MARKER* marker = m_filteredMarkers[ aIndex ];
369
370 return marker ? std::static_pointer_cast<ERC_ITEM>( marker->GetRCItem() ) : nullptr;
371}
372
373
374std::shared_ptr<RC_ITEM> SHEETLIST_ERC_ITEMS_PROVIDER::GetItem( int aIndex ) const
375{
376 return GetERCItem( aIndex );
377}
378
379
380void SHEETLIST_ERC_ITEMS_PROVIDER::DeleteItem( int aIndex, bool aDeep )
381{
382 SCH_MARKER* marker = m_filteredMarkers[ aIndex ];
383 m_filteredMarkers.erase( m_filteredMarkers.begin() + aIndex );
384
385 if( aDeep )
386 {
387 SCH_SCREENS screens( m_schematic->Root() );
388 screens.DeleteMarker( marker );
389 }
390}
391
392
const char * name
Definition: DXF_plotter.cpp:56
static std::vector< std::reference_wrapper< RC_ITEM > > GetItemsWithSeverities()
Definition: erc_item.h:76
Container for ERC settings.
Definition: erc_settings.h:114
static PIN_ERROR m_defaultPinMap[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL]
Default Look up table which gives the ERC error level for a pair of connected pins.
Definition: erc_settings.h:182
SEVERITY GetSeverity(int aErrorCode) const
ERC_SETTINGS(JSON_SETTINGS *aParent, const std::string &aPath)
void ResetPinMap()
void SetSeverity(int aErrorCode, SEVERITY aSeverity)
virtual ~ERC_SETTINGS()
PIN_ERROR GetPinMapValue(int aFirstType, int aSecondType) const
Definition: erc_settings.h:141
std::map< int, SEVERITY > m_ERCSeverities
Definition: erc_settings.h:173
std::set< wxString > m_ErcExclusions
Definition: erc_settings.h:174
static int m_PinMinDrive[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL]
Look up table which gives the minimal drive for a pair of connected pins on a net.
Definition: erc_settings.h:178
void SetPinMapValue(int aFirstType, int aSecondType, PIN_ERROR aValue)
Definition: erc_settings.h:153
PIN_ERROR m_PinMap[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL]
Definition: erc_settings.h:176
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
void ReleaseNestedSettings(NESTED_SETTINGS *aSettings)
Saves and frees a nested settings object, if it exists within this one.
bool IsExcluded() const
Definition: marker_base.h:97
std::shared_ptr< RC_ITEM > GetRCItem() const
Definition: marker_base.h:105
enum TYPEMARKER GetMarkerType() const
Definition: marker_base.h:95
NESTED_SETTINGS is a JSON_SETTINGS that lives inside a JSON_SETTINGS.
JSON_SETTINGS * m_parent
A pointer to the parent object to load and store from.
Like a normal param, but with custom getter and setter functions.
Definition: parameters.h:282
A holder for a rule check item, DRC in Pcbnew or ERC in Eeschema.
Definition: rc_item.h:75
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
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:212
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:662
void DeleteMarker(SCH_MARKER *aMarker)
Delete a specific marker.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
int GetCount(int aSeverity=-1) const override
void SetSeverities(int aSeverities) override
void visitMarkers(std::function< void(SCH_MARKER *)> aVisitor) const
void DeleteItem(int aIndex, bool aDeep) override
Remove (and optionally deletes) the indexed item from the list.
std::shared_ptr< ERC_ITEM > GetERCItem(int aIndex) const
std::vector< SCH_MARKER * > m_filteredMarkers
Definition: erc_settings.h:195
std::shared_ptr< RC_ITEM > GetItem(int aIndex) const override
Retrieve a RC_ITEM by index.
const int ercSettingsSchemaVersion
#define ERR
#define WAR
#define OK
#define DRV
Definition: erc_settings.h:102
@ ERCE_UNSPECIFIED
Definition: erc_settings.h:38
@ ERCE_DRIVER_CONFLICT
Conflicting drivers (labels, etc) on a subgraph.
Definition: erc_settings.h:61
@ ERCE_SIMILAR_LABELS
2 labels are equal for case insensitive comparisons.
Definition: erc_settings.h:51
@ ERCE_FIRST
Definition: erc_settings.h:39
@ ERCE_ENDPOINT_OFF_GRID
Pin or wire-end off grid.
Definition: erc_settings.h:41
@ ERCE_LAST
Definition: erc_settings.h:81
@ ERCE_BUS_ENTRY_CONFLICT
A wire connected to a bus doesn't match the bus.
Definition: erc_settings.h:62
@ ERCE_GLOBLABEL
A global label is unique.
Definition: erc_settings.h:69
@ ERCE_NOCONNECT_NOT_CONNECTED
A no connect symbol is not connected to anything.
Definition: erc_settings.h:49
@ ERCE_SIMULATION_MODEL
An error was found in the simulation model.
Definition: erc_settings.h:71
@ 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_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_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_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
#define NOD
Definition: erc_settings.h:104
#define NPI
Types of drive on a net (used for legacy ERC)
Definition: erc_settings.h:101
#define ELECTRICAL_PINTYPES_TOTAL
Definition: pin_type.h:53
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_UNDEFINED
@ RPT_SEVERITY_EXCLUSION
@ RPT_SEVERITY_IGNORE
@ SCH_MARKER_T
Definition: typeinfo.h:131
wxString SeverityToString(const SEVERITY &aSeverity)
Definition: ui_common.cpp:59