Templatize MigrateSimModel() so it can be used on LIB_SYMBOLs as well.
Fixes https://gitlab.com/kicad/code/kicad/issues/13080
This commit is contained in:
parent
cfbf14ebfd
commit
8931e55dd2
|
@ -2,6 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2022 CERN
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -39,11 +40,12 @@
|
|||
#include <settings/color_settings.h>
|
||||
|
||||
|
||||
LIB_FIELD::LIB_FIELD( LIB_SYMBOL* aParent, int aId ) :
|
||||
LIB_FIELD::LIB_FIELD( LIB_SYMBOL* aParent, int aId, const wxString& aName ) :
|
||||
LIB_ITEM( LIB_FIELD_T, aParent ),
|
||||
EDA_TEXT( schIUScale )
|
||||
{
|
||||
Init( aId );
|
||||
m_name = aName;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2022 CERN
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -63,7 +64,7 @@ public:
|
|||
|
||||
LIB_FIELD( int aId, const wxString& aName );
|
||||
|
||||
LIB_FIELD( LIB_SYMBOL* aParent, int aId = 2 );
|
||||
LIB_FIELD( LIB_SYMBOL* aParent, int aId = 2, const wxString& aName = wxEmptyString );
|
||||
|
||||
// Do not create a copy constructor. The one generated by the compiler is adequate.
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2022 CERN
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -1181,6 +1182,32 @@ LIB_FIELD& LIB_SYMBOL::GetDatasheetField()
|
|||
}
|
||||
|
||||
|
||||
wxString LIB_SYMBOL::GetPrefix()
|
||||
{
|
||||
wxString refDesignator = GetFieldById( REFERENCE_FIELD )->GetText();
|
||||
|
||||
refDesignator.Replace( "~", " " );
|
||||
|
||||
wxString prefix = refDesignator;
|
||||
|
||||
while( prefix.Length() )
|
||||
{
|
||||
wxUniCharRef last = prefix.Last();
|
||||
|
||||
if( ( last >= '0' && last <= '9' ) || last == '?' || last == '*' )
|
||||
prefix.RemoveLast();
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Avoid a prefix containing trailing/leading spaces
|
||||
prefix.Trim( true );
|
||||
prefix.Trim( false );
|
||||
|
||||
return prefix;
|
||||
}
|
||||
|
||||
|
||||
int LIB_SYMBOL::UpdateFieldOrdinals()
|
||||
{
|
||||
int retv = 0;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2022 CERN
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -276,6 +277,8 @@ public:
|
|||
*/
|
||||
void AddField( LIB_FIELD* aField );
|
||||
|
||||
void AddField( LIB_FIELD& aField ) { AddField( new LIB_FIELD( aField ) ); }
|
||||
|
||||
/**
|
||||
* Find a field within this symbol matching \a aFieldName and returns it
|
||||
* or NULL if not found.
|
||||
|
@ -304,6 +307,8 @@ public:
|
|||
/** Return reference to the datasheet field. */
|
||||
LIB_FIELD& GetDatasheetField();
|
||||
|
||||
wxString GetPrefix();
|
||||
|
||||
/**
|
||||
* Order optional field indices.
|
||||
*
|
||||
|
@ -385,6 +390,8 @@ public:
|
|||
*/
|
||||
void RemoveDrawItem( LIB_ITEM* aItem );
|
||||
|
||||
void RemoveField( LIB_FIELD* aField ) { RemoveDrawItem( aField ); }
|
||||
|
||||
/**
|
||||
* Return the next draw object pointer.
|
||||
*
|
||||
|
|
|
@ -73,6 +73,12 @@ SCH_FIELD::SCH_FIELD( const VECTOR2I& aPos, int aFieldId, SCH_ITEM* aParent,
|
|||
}
|
||||
|
||||
|
||||
SCH_FIELD::SCH_FIELD( SCH_ITEM* aParent, int aFieldId, const wxString& aName ) :
|
||||
SCH_FIELD( VECTOR2I(), aFieldId, aParent, aName )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SCH_FIELD::SCH_FIELD( const SCH_FIELD& aField ) :
|
||||
SCH_ITEM( aField ),
|
||||
EDA_TEXT( aField )
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2022 CERN
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -52,6 +53,8 @@ public:
|
|||
SCH_FIELD( const VECTOR2I& aPos, int aFieldId, SCH_ITEM* aParent,
|
||||
const wxString& aName = wxEmptyString );
|
||||
|
||||
SCH_FIELD( SCH_ITEM* aParent, int aFieldId, const wxString& aName = wxEmptyString );
|
||||
|
||||
SCH_FIELD( const SCH_FIELD& aText );
|
||||
|
||||
~SCH_FIELD()
|
||||
|
|
|
@ -83,7 +83,7 @@ void SCH_PLUGIN::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
|
|||
|
||||
|
||||
LIB_SYMBOL* SCH_PLUGIN::LoadSymbol( const wxString& aLibraryPath, const wxString& aSymbolName,
|
||||
const STRING_UTF8_MAP* aProperties )
|
||||
const STRING_UTF8_MAP* aProperties )
|
||||
{
|
||||
// not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
|
||||
not_implemented( this, __FUNCTION__ );
|
||||
|
|
|
@ -1856,188 +1856,6 @@ void SCH_SCREEN::MigrateSimModels()
|
|||
for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
|
||||
{
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
|
||||
migrateSimModel( *symbol );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_SCREEN::migrateSimModel( SCH_SYMBOL& aSymbol )
|
||||
{
|
||||
if( aSymbol.FindField( SIM_MODEL::DEVICE_TYPE_FIELD )
|
||||
|| aSymbol.FindField( SIM_MODEL::TYPE_FIELD )
|
||||
|| aSymbol.FindField( SIM_MODEL::PINS_FIELD )
|
||||
|| aSymbol.FindField( SIM_MODEL::PARAMS_FIELD ) )
|
||||
{
|
||||
// Has a V7 model field -- skip.
|
||||
return;
|
||||
}
|
||||
|
||||
wxString prefix = aSymbol.GetPrefix();
|
||||
wxString value = aSymbol.GetValueFieldText( true );
|
||||
|
||||
wxString spiceType;
|
||||
wxString spiceModel;
|
||||
wxString spiceLib;
|
||||
wxString pinMap;
|
||||
|
||||
if( aSymbol.FindField( wxT( "Spice_Primitive" ) )
|
||||
|| aSymbol.FindField( wxT( "Spice_Node_Sequence" ) )
|
||||
|| aSymbol.FindField( wxT( "Spice_Model" ) )
|
||||
|| aSymbol.FindField( wxT( "Spice_Netlist_Enabled" ) )
|
||||
|| aSymbol.FindField( wxT( "Spice_Lib_File" ) ) )
|
||||
{
|
||||
if( SCH_FIELD* primitiveField = aSymbol.FindField( wxT( "Spice_Primitive" ) ) )
|
||||
{
|
||||
spiceType = primitiveField->GetText();
|
||||
aSymbol.RemoveField( wxT( "Spice_Primitive" ) );
|
||||
}
|
||||
|
||||
if( SCH_FIELD* nodeSequenceField = aSymbol.FindField( wxT( "Spice_Node_Sequence" ) ) )
|
||||
{
|
||||
const wxString delimiters( "{:,; }" );
|
||||
const wxString& nodeSequence = nodeSequenceField->GetText();
|
||||
|
||||
if( nodeSequence != "" )
|
||||
{
|
||||
wxStringTokenizer tkz( nodeSequence, delimiters );
|
||||
|
||||
for( long modelPinNumber = 1; tkz.HasMoreTokens(); ++modelPinNumber )
|
||||
{
|
||||
long symbolPinNumber = 1;
|
||||
tkz.GetNextToken().ToLong( &symbolPinNumber );
|
||||
|
||||
if( modelPinNumber != 1 )
|
||||
pinMap.Append( " " );
|
||||
|
||||
pinMap.Append( wxString::Format( "%ld=%ld", symbolPinNumber, modelPinNumber ) );
|
||||
}
|
||||
}
|
||||
|
||||
aSymbol.RemoveField( wxT( "Spice_Node_Sequence" ) );
|
||||
}
|
||||
|
||||
if( SCH_FIELD* modelField = aSymbol.FindField( wxT( "Spice_Model" ) ) )
|
||||
{
|
||||
spiceModel = modelField->GetText();
|
||||
aSymbol.RemoveField( wxT( "Spice_Model" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
spiceModel = aSymbol.GetValueFieldText( true );
|
||||
}
|
||||
|
||||
if( SCH_FIELD* netlistEnabledField = aSymbol.FindField( wxT( "Spice_Netlist_Enabled" ) ) )
|
||||
{
|
||||
wxString netlistEnabled = netlistEnabledField->GetText().Lower();
|
||||
|
||||
if( netlistEnabled.StartsWith( wxT( "0" ) )
|
||||
|| netlistEnabled.StartsWith( wxT( "n" ) )
|
||||
|| netlistEnabled.StartsWith( wxT( "f" ) ) )
|
||||
{
|
||||
SCH_FIELD enableField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::ENABLE_FIELD );
|
||||
}
|
||||
}
|
||||
|
||||
if( SCH_FIELD* libFileField = aSymbol.FindField( wxT( "Spice_Lib_File" ) ) )
|
||||
{
|
||||
spiceLib = libFileField->GetText();
|
||||
aSymbol.RemoveField( wxT( "Spice_Lib_File" ) );
|
||||
}
|
||||
}
|
||||
else if( prefix == wxT( "V" ) || prefix == wxT( "I" ) )
|
||||
{
|
||||
spiceModel = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Auto convert some legacy fields used in the middle of 7.0 development...
|
||||
|
||||
if( SCH_FIELD* legacyDevice = aSymbol.FindField( wxT( "Sim_Type" ) ) )
|
||||
{
|
||||
legacyDevice->SetName( SIM_MODEL::TYPE_FIELD );
|
||||
}
|
||||
|
||||
if( SCH_FIELD* legacyDevice = aSymbol.FindField( wxT( "Sim_Device" ) ) )
|
||||
{
|
||||
legacyDevice->SetName( SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
}
|
||||
|
||||
if( SCH_FIELD* legacyPins = aSymbol.FindField( wxT( "Sim_Pins" ) ) )
|
||||
{
|
||||
// Migrate pins from array of indexes to name-value-pairs
|
||||
wxArrayString pinIndexes;
|
||||
wxString pins;
|
||||
|
||||
wxStringSplit( legacyPins->GetText(), pinIndexes, ' ' );
|
||||
|
||||
if( SIM_MODEL_IDEAL::InferSimParams( prefix, value ).length() )
|
||||
{
|
||||
if( pinIndexes[0] == wxT( "2" ) )
|
||||
pins = "1=- 2=+";
|
||||
else
|
||||
pins = "1=+ 2=-";
|
||||
}
|
||||
else
|
||||
{
|
||||
for( unsigned ii = 0; ii < pinIndexes.size(); ++ii )
|
||||
{
|
||||
if( ii > 0 )
|
||||
pins.Append( wxS( " " ) );
|
||||
|
||||
pins.Append( wxString::Format( wxT( "%u=%s" ), ii + 1, pinIndexes[ ii ] ) );
|
||||
}
|
||||
}
|
||||
|
||||
legacyPins->SetName( SIM_MODEL::PINS_FIELD );
|
||||
legacyPins->SetText( pins );
|
||||
}
|
||||
|
||||
if( SCH_FIELD* legacyPins = aSymbol.FindField( wxT( "Sim_Params" ) ) )
|
||||
{
|
||||
legacyPins->SetName( SIM_MODEL::PARAMS_FIELD );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert a plaintext model as a substitute.
|
||||
|
||||
SCH_FIELD deviceTypeField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
deviceTypeField.SetText( SIM_MODEL::DeviceInfo( SIM_MODEL::DEVICE_T::SPICE ).fieldValue );
|
||||
aSymbol.AddField( deviceTypeField );
|
||||
|
||||
SCH_FIELD paramsField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::PARAMS_FIELD );
|
||||
paramsField.SetText( wxString::Format( "type=\"%s\" model=\"%s\" lib=\"%s\"",
|
||||
spiceType, spiceModel, spiceLib ) );
|
||||
aSymbol.AddField( paramsField );
|
||||
|
||||
// Legacy models by default get linear pin mapping.
|
||||
if( pinMap != "" )
|
||||
{
|
||||
SCH_FIELD pinsField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::PINS_FIELD );
|
||||
|
||||
pinsField.SetText( pinMap );
|
||||
aSymbol.AddField( pinsField );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString pins;
|
||||
|
||||
for( unsigned ii = 0; ii < aSymbol.GetLibPins().size(); ++ii )
|
||||
{
|
||||
if( ii > 0 )
|
||||
pins.Append( wxS( " " ) );
|
||||
|
||||
pins.Append( wxString::Format( wxT( "%u=%u" ), ii + 1, ii + 1 ) );
|
||||
}
|
||||
|
||||
SCH_FIELD pinsField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::PINS_FIELD );
|
||||
pinsField.SetText( pins );
|
||||
aSymbol.AddField( pinsField );
|
||||
SIM_MODEL::MigrateSimModel<SCH_SYMBOL, SCH_FIELD>( *symbol );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -723,10 +723,12 @@ void SCH_SYMBOL::UpdatePrefix()
|
|||
|
||||
while( prefix.Length() )
|
||||
{
|
||||
if( ( prefix.Last() < '0' || prefix.Last() > '9' ) && prefix.Last() != '?' )
|
||||
break;
|
||||
wxUniCharRef last = prefix.Last();
|
||||
|
||||
prefix.RemoveLast();
|
||||
if( ( last >= '0' && last <= '9' ) || last == '?' || last == '*' )
|
||||
prefix.RemoveLast();
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Avoid a prefix containing trailing/leading spaces
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2014 Dick Hollenbeck, dick@softplc.com
|
||||
* Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2022 CERN
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -438,6 +439,8 @@ public:
|
|||
*/
|
||||
void RemoveField( const wxString& aFieldName );
|
||||
|
||||
void RemoveField( SCH_FIELD* aField ) { RemoveField( aField->GetName() ); }
|
||||
|
||||
/**
|
||||
* Search for a #SCH_FIELD with \a aFieldName
|
||||
*
|
||||
|
@ -521,6 +524,8 @@ public:
|
|||
*/
|
||||
std::vector<LIB_PIN*> GetLibPins() const;
|
||||
|
||||
size_t GetPinCount() { return GetLibPins().size(); }
|
||||
|
||||
SCH_PIN* GetPin( LIB_PIN* aLibPin ) const;
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 CERN
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -22,7 +23,9 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#include <lib_symbol.h>
|
||||
#include <sch_symbol.h>
|
||||
#include <confirm.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
#include <sim/sim_model.h>
|
||||
#include <sim/sim_model_behavioral.h>
|
||||
|
@ -628,6 +631,7 @@ void SIM_MODEL::AddPin( const PIN& aPin )
|
|||
m_pins.push_back( aPin );
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL::ClearPins()
|
||||
{
|
||||
m_pins.clear();
|
||||
|
@ -916,23 +920,19 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType )
|
|||
|
||||
|
||||
SIM_MODEL::SIM_MODEL( TYPE aType ) :
|
||||
SIM_MODEL( aType,
|
||||
std::make_unique<SPICE_GENERATOR>( *this ),
|
||||
std::make_unique<SIM_SERDE>( *this ) )
|
||||
{
|
||||
}
|
||||
|
||||
SIM_MODEL::SIM_MODEL( TYPE aType,
|
||||
std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator ) :
|
||||
SIM_MODEL( aType,
|
||||
std::move( aSpiceGenerator ),
|
||||
SIM_MODEL( aType, std::make_unique<SPICE_GENERATOR>( *this ),
|
||||
std::make_unique<SIM_SERDE>( *this ) )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SIM_MODEL::SIM_MODEL( TYPE aType,
|
||||
std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator,
|
||||
SIM_MODEL::SIM_MODEL( TYPE aType, std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator ) :
|
||||
SIM_MODEL( aType, std::move( aSpiceGenerator ), std::make_unique<SIM_SERDE>( *this ) )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SIM_MODEL::SIM_MODEL( TYPE aType, std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator,
|
||||
std::unique_ptr<SIM_SERDE> aSerde ) :
|
||||
m_baseModel( nullptr ),
|
||||
m_serde( std::move( aSerde ) ),
|
||||
|
@ -1004,3 +1004,189 @@ bool SIM_MODEL::requiresSpiceModelLine() const
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <typename T_symbol, typename T_field>
|
||||
void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol )
|
||||
{
|
||||
if( aSymbol.FindField( SIM_MODEL::DEVICE_TYPE_FIELD )
|
||||
|| aSymbol.FindField( SIM_MODEL::TYPE_FIELD )
|
||||
|| aSymbol.FindField( SIM_MODEL::PINS_FIELD )
|
||||
|| aSymbol.FindField( SIM_MODEL::PARAMS_FIELD ) )
|
||||
{
|
||||
// Has a V7 model field -- skip.
|
||||
return;
|
||||
}
|
||||
|
||||
wxString prefix = aSymbol.GetPrefix();
|
||||
wxString value;
|
||||
|
||||
// Yes, the Value field is always present, but Coverity doesn't know that...
|
||||
if( T_field* valueField = aSymbol.FindField( wxT( "Value" ) ) )
|
||||
value = valueField->GetText();
|
||||
|
||||
wxString spiceType;
|
||||
wxString spiceModel;
|
||||
wxString spiceLib;
|
||||
wxString pinMap;
|
||||
|
||||
if( aSymbol.FindField( wxT( "Spice_Primitive" ) )
|
||||
|| aSymbol.FindField( wxT( "Spice_Node_Sequence" ) )
|
||||
|| aSymbol.FindField( wxT( "Spice_Model" ) )
|
||||
|| aSymbol.FindField( wxT( "Spice_Netlist_Enabled" ) )
|
||||
|| aSymbol.FindField( wxT( "Spice_Lib_File" ) ) )
|
||||
{
|
||||
if( T_field* primitiveField = aSymbol.FindField( wxT( "Spice_Primitive" ) ) )
|
||||
{
|
||||
spiceType = primitiveField->GetText();
|
||||
aSymbol.RemoveField( primitiveField );
|
||||
}
|
||||
|
||||
if( T_field* nodeSequenceField = aSymbol.FindField( wxT( "Spice_Node_Sequence" ) ) )
|
||||
{
|
||||
const wxString delimiters( "{:,; }" );
|
||||
const wxString& nodeSequence = nodeSequenceField->GetText();
|
||||
|
||||
if( nodeSequence != "" )
|
||||
{
|
||||
wxStringTokenizer tkz( nodeSequence, delimiters );
|
||||
|
||||
for( long modelPinNumber = 1; tkz.HasMoreTokens(); ++modelPinNumber )
|
||||
{
|
||||
long symbolPinNumber = 1;
|
||||
tkz.GetNextToken().ToLong( &symbolPinNumber );
|
||||
|
||||
if( modelPinNumber != 1 )
|
||||
pinMap.Append( " " );
|
||||
|
||||
pinMap.Append( wxString::Format( "%ld=%ld", symbolPinNumber, modelPinNumber ) );
|
||||
}
|
||||
}
|
||||
|
||||
aSymbol.RemoveField( nodeSequenceField );
|
||||
}
|
||||
|
||||
if( T_field* modelField = aSymbol.FindField( wxT( "Spice_Model" ) ) )
|
||||
{
|
||||
spiceModel = modelField->GetText();
|
||||
aSymbol.RemoveField( modelField );
|
||||
}
|
||||
else
|
||||
{
|
||||
spiceModel = value;
|
||||
}
|
||||
|
||||
if( T_field* netlistEnabledField = aSymbol.FindField( wxT( "Spice_Netlist_Enabled" ) ) )
|
||||
{
|
||||
wxString netlistEnabled = netlistEnabledField->GetText().Lower();
|
||||
|
||||
if( netlistEnabled.StartsWith( wxT( "0" ) )
|
||||
|| netlistEnabled.StartsWith( wxT( "n" ) )
|
||||
|| netlistEnabled.StartsWith( wxT( "f" ) ) )
|
||||
{
|
||||
T_field enableField( &aSymbol, aSymbol.GetFieldCount(), SIM_MODEL::ENABLE_FIELD );
|
||||
}
|
||||
}
|
||||
|
||||
if( T_field* libFileField = aSymbol.FindField( wxT( "Spice_Lib_File" ) ) )
|
||||
{
|
||||
spiceLib = libFileField->GetText();
|
||||
aSymbol.RemoveField( libFileField );
|
||||
}
|
||||
}
|
||||
else if( prefix == wxT( "V" ) || prefix == wxT( "I" ) )
|
||||
{
|
||||
spiceModel = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Auto convert some legacy fields used in the middle of 7.0 development...
|
||||
|
||||
if( T_field* legacyDevice = aSymbol.FindField( wxT( "Sim_Type" ) ) )
|
||||
{
|
||||
legacyDevice->SetName( SIM_MODEL::TYPE_FIELD );
|
||||
}
|
||||
|
||||
if( T_field* legacyDevice = aSymbol.FindField( wxT( "Sim_Device" ) ) )
|
||||
{
|
||||
legacyDevice->SetName( SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
}
|
||||
|
||||
if( T_field* legacyPins = aSymbol.FindField( wxT( "Sim_Pins" ) ) )
|
||||
{
|
||||
// Migrate pins from array of indexes to name-value-pairs
|
||||
wxArrayString pinIndexes;
|
||||
wxString pins;
|
||||
|
||||
wxStringSplit( legacyPins->GetText(), pinIndexes, ' ' );
|
||||
|
||||
if( SIM_MODEL_IDEAL::InferSimParams( prefix, value ).length() )
|
||||
{
|
||||
if( pinIndexes[0] == wxT( "2" ) )
|
||||
pins = "1=- 2=+";
|
||||
else
|
||||
pins = "1=+ 2=-";
|
||||
}
|
||||
else
|
||||
{
|
||||
for( unsigned ii = 0; ii < pinIndexes.size(); ++ii )
|
||||
{
|
||||
if( ii > 0 )
|
||||
pins.Append( wxS( " " ) );
|
||||
|
||||
pins.Append( wxString::Format( wxT( "%u=%s" ), ii + 1, pinIndexes[ ii ] ) );
|
||||
}
|
||||
}
|
||||
|
||||
legacyPins->SetName( SIM_MODEL::PINS_FIELD );
|
||||
legacyPins->SetText( pins );
|
||||
}
|
||||
|
||||
if( T_field* legacyPins = aSymbol.FindField( wxT( "Sim_Params" ) ) )
|
||||
{
|
||||
legacyPins->SetName( SIM_MODEL::PARAMS_FIELD );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert a plaintext model as a substitute.
|
||||
|
||||
T_field deviceTypeField( &aSymbol, aSymbol.GetFieldCount(), SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
deviceTypeField.SetText( SIM_MODEL::DeviceInfo( SIM_MODEL::DEVICE_T::SPICE ).fieldValue );
|
||||
aSymbol.AddField( deviceTypeField );
|
||||
|
||||
T_field paramsField( &aSymbol, aSymbol.GetFieldCount(), SIM_MODEL::PARAMS_FIELD );
|
||||
paramsField.SetText( wxString::Format( "type=\"%s\" model=\"%s\" lib=\"%s\"",
|
||||
spiceType, spiceModel, spiceLib ) );
|
||||
aSymbol.AddField( paramsField );
|
||||
|
||||
// Legacy models by default get linear pin mapping.
|
||||
if( pinMap != "" )
|
||||
{
|
||||
T_field pinsField( &aSymbol, aSymbol.GetFieldCount(), SIM_MODEL::PINS_FIELD );
|
||||
|
||||
pinsField.SetText( pinMap );
|
||||
aSymbol.AddField( pinsField );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString pins;
|
||||
|
||||
for( unsigned ii = 0; ii < aSymbol.GetPinCount(); ++ii )
|
||||
{
|
||||
if( ii > 0 )
|
||||
pins.Append( wxS( " " ) );
|
||||
|
||||
pins.Append( wxString::Format( wxT( "%u=%u" ), ii + 1, ii + 1 ) );
|
||||
}
|
||||
|
||||
T_field pinsField( &aSymbol, aSymbol.GetFieldCount(), SIM_MODEL::PINS_FIELD );
|
||||
pinsField.SetText( pins );
|
||||
aSymbol.AddField( pinsField );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template void SIM_MODEL::MigrateSimModel<SCH_SYMBOL, SCH_FIELD>( SCH_SYMBOL& aSymbol );
|
||||
template void SIM_MODEL::MigrateSimModel<LIB_SYMBOL, LIB_FIELD>( LIB_SYMBOL& aSymbol );
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 CERN
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -518,6 +519,9 @@ public:
|
|||
}
|
||||
bool IsStoredInValue() const { return m_isStoredInValue; }
|
||||
|
||||
template <class T_symbol, class T_field>
|
||||
static void MigrateSimModel( T_symbol& aSymbol );
|
||||
|
||||
protected:
|
||||
static std::unique_ptr<SIM_MODEL> Create( TYPE aType );
|
||||
|
||||
|
@ -535,11 +539,6 @@ protected:
|
|||
std::unique_ptr<SIM_SERDE> m_serde;
|
||||
|
||||
private:
|
||||
static TYPE readTypeFromSpiceStrings( const std::string& aTypeString,
|
||||
const std::string& aLevel = "",
|
||||
const std::string& aVersion = "",
|
||||
bool aSkipDefaultLevel = true );
|
||||
|
||||
template <typename T>
|
||||
void doReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields );
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2022 CERN
|
||||
* Copyright (C) 2016-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -34,7 +35,7 @@
|
|||
#include <lib_symbol.h>
|
||||
|
||||
#include <wx/dir.h>
|
||||
|
||||
#include "sim/sim_model.h"
|
||||
|
||||
#define OPT_SEP '|' ///< options separator character
|
||||
|
||||
|
@ -393,16 +394,18 @@ LIB_SYMBOL* SYMBOL_LIB_TABLE::LoadSymbol( const wxString& aNickname, const wxStr
|
|||
LIB_SYMBOL* symbol = row->plugin->LoadSymbol( row->GetFullURI( true ), aSymbolName,
|
||||
row->GetProperties() );
|
||||
|
||||
// The library cannot know its own name, because it might have been renamed or moved.
|
||||
// Therefore footprints cannot know their own library nickname when residing in
|
||||
// a symbol library.
|
||||
// Only at this API layer can we tell the symbol about its actual library nickname.
|
||||
if( symbol )
|
||||
{
|
||||
// The library cannot know its own name, because it might have been renamed or moved.
|
||||
// Therefore footprints cannot know their own library nickname when residing in
|
||||
// a symbol library.
|
||||
// Only at this API layer can we tell the symbol about its actual library nickname.
|
||||
LIB_ID id = symbol->GetLibId();
|
||||
|
||||
id.SetLibNickname( row->GetNickName() );
|
||||
symbol->SetLibId( id );
|
||||
|
||||
SIM_MODEL::MigrateSimModel<LIB_SYMBOL, LIB_FIELD>( *symbol );
|
||||
}
|
||||
|
||||
return symbol;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2004-2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2022 CERN
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -43,6 +44,7 @@
|
|||
#include <wx/log.h>
|
||||
#include <wx/progdlg.h>
|
||||
#include <wx/tokenzr.h>
|
||||
#include "sim/sim_model.h"
|
||||
|
||||
SYMBOL_LIB::SYMBOL_LIB( SCH_LIB_TYPE aType, const wxString& aFileName,
|
||||
SCH_IO_MGR::SCH_FILE_T aPluginType ) :
|
||||
|
@ -159,11 +161,16 @@ LIB_SYMBOL* SYMBOL_LIB::FindSymbol( const wxString& aName ) const
|
|||
{
|
||||
LIB_SYMBOL* symbol = m_plugin->LoadSymbol( fileName.GetFullPath(), aName, m_properties.get() );
|
||||
|
||||
// Set the library to this even though technically the legacy cache plugin owns the
|
||||
// symbols. This allows the symbol library table conversion tool to determine the
|
||||
// correct library where the symbol was found.
|
||||
if( symbol && !symbol->GetLib() )
|
||||
symbol->SetLib( const_cast<SYMBOL_LIB*>( this ) );
|
||||
if( symbol )
|
||||
{
|
||||
// Set the library to this even though technically the legacy cache plugin owns the
|
||||
// symbols. This allows the symbol library table conversion tool to determine the
|
||||
// correct library where the symbol was found.
|
||||
if( !symbol->GetLib() )
|
||||
symbol->SetLib( const_cast<SYMBOL_LIB*>( this ) );
|
||||
|
||||
SIM_MODEL::MigrateSimModel<LIB_SYMBOL, LIB_FIELD>( *symbol );
|
||||
}
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue