diff --git a/eeschema/netform.cpp b/eeschema/netform.cpp index 0fb2680075..cda8e52c03 100644 --- a/eeschema/netform.cpp +++ b/eeschema/netform.cpp @@ -48,7 +48,10 @@ #include "sch_component.h" #include "sch_text.h" #include "sch_sheet.h" -#include "template_fieldnames.h" +#include "template_fieldnames.h" +#include + + #include "xnode.h" // also nests: @@ -1195,18 +1198,26 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames ) wxArrayString spiceCommandAtBeginFile; wxArrayString spiceCommandAtEndFile; wxString msg; - wxString netName; + wxString netName; + +#define BUFYPOS_LEN 4 +#define WORSE_CASE_PIN_COUNT 500 + long int NodeSeqIndexArray[WORSE_CASE_PIN_COUNT]; + int NodeSeqIndex=0; + -#define BUFYPOS_LEN 4 wxChar bufnum[BUFYPOS_LEN + 1]; DateAndTime( Line ); - ret |= fprintf( f, "* %s (Spice format) creation date: %s\n\n", NETLIST_HEAD_STRING, Line ); - - // Prepare list of nets generation (not used here, but... - for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ ) - g_NetObjectslist[ii]->m_Flag = 0; + ret |= fprintf( f, "* %s (Spice format) creation date: %s\n\n", NETLIST_HEAD_STRING, Line ); + + // Prepare list of nets generation (not used here, but... + for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ ) + g_NetObjectslist[ii]->m_Flag = 0; + + ret |= fprintf( f, "* To exclude a component from the Spice Netlist add [Spice_Netlist_Enabled] user FIELD set to: N\n"); + ret |= fprintf( f, "* To reorder the component spice node sequence add [Spice_Node_Sequence] user FIELD and define sequence: 2,1,0\n"); // Create text list starting by [.-]pspice , or [.-]gnucap (simulator // commands) and create text list starting by [+]pspice , or [+]gnucap @@ -1280,6 +1291,7 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames ) for( SCH_SHEET_PATH* sheet = sheetList.GetFirst(); sheet; sheet = sheetList.GetNext() ) { + fprintf(f,"*Sheet Name:%s\n",TO_UTF8(sheet->PathHumanReadable())); for( EDA_ITEM* item = sheet->LastDrawList(); item; item = item->Next() ) { SCH_COMPONENT* comp = findNextComponentAndCreatePinList( item, sheet ); @@ -1287,13 +1299,77 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames ) break; item = comp; - + + //Check if Component should be excluded from Netlist + #define SPICE_ENB_FIELD wxT("Spice_Netlist_Enabled") + //Reset NodeSeqIndex Count: + NodeSeqIndex=0; + //Initialize NodeSeqArray to all UNUSED: + #define UNUSED_NODE_FLAG -1 + memset(NodeSeqIndexArray,UNUSED_NODE_FLAG,sizeof(NodeSeqIndexArray[WORSE_CASE_PIN_COUNT])); + + //Check to see if Component should be removed from Spice Netlist: + wxString DisableStr = wxT("N"); + SCH_FIELD* Netlist_Enabled_obj = comp->FindField(SPICE_ENB_FIELD); + if(Netlist_Enabled_obj!=NULL){ + wxString Netlist_Enabled_Value = Netlist_Enabled_obj->m_Text; + if(Netlist_Enabled_Value.IsEmpty()) break; + if(Netlist_Enabled_Value.IsNull()) break; + if( Netlist_Enabled_Value.CmpNoCase(DisableStr)==0 ){ + continue; + } + } + + //Check if Alternative Pin Sequence is Available: + #define SPICE_SEQ_FIELD wxT("Spice_Node_Sequence") + SCH_FIELD* Spice_Seq_obj = comp->FindField(SPICE_SEQ_FIELD); + if(Spice_Seq_obj!=NULL){ + //Get String containing the Sequence of Nodes: + wxString NodeSeqIndexLineStr = Spice_Seq_obj->m_Text; + //Verify Field Exists and is not empty: + if(NodeSeqIndexLineStr.IsEmpty()) break; + if(NodeSeqIndexLineStr.IsNull()) break; + //Parse Sequence List Textbox into List of Integer Array: + wxString Delimeters = wxT("{:,; }"); + wxStringTokenizer tkz(NodeSeqIndexLineStr, Delimeters); + while ( tkz.HasMoreTokens() ){ + wxString NodeSeqIndexStr = tkz.GetNextToken(); + if( (NodeSeqIndexStr.IsNumber()) && (NodeSeqIndex < WORSE_CASE_PIN_COUNT) ){ + if(NodeSeqIndexStr.ToLong(&NodeSeqIndexArray[NodeSeqIndex],10)){ + if(NodeSeqIndexArray[NodeSeqIndex]>=0){ + NodeSeqIndex++; + } + } + } + } + } ret |= fprintf( f, "%s ", TO_UTF8( comp->GetRef( sheet ) ) ); + + + // Write pin list: + int ActivePinIndex = 0; - // Write pin list: for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ ) - { - NETLIST_OBJECT* pin = m_SortedComponentPinList[ii]; + { + //Case of Alt Sequence definition with Unused/Invalid Node index: + //Valid used Node Indexes are in the set {0,1,2,...m_SortedComponentPinList.size()-1} + long int MaxPartPinList = m_SortedComponentPinList.size(); + if( (NodeSeqIndex!=0) ){ + if( (NodeSeqIndexArray[ii] <= UNUSED_NODE_FLAG) || + (NodeSeqIndexArray[ii] >= MaxPartPinList) ){ + continue; + } + } + //Case of Alt Pin Sequence in control: + if(NodeSeqIndex!=0){ + ActivePinIndex = NodeSeqIndexArray[ii]; + } + //Case of Standard Pin Sequence in control: + else{ + ActivePinIndex = ii; + } + NETLIST_OBJECT* pin = m_SortedComponentPinList[ActivePinIndex]; + if( !pin ) continue; @@ -1314,33 +1390,43 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames ) ret |= fprintf( f, " %d", pin->GetNet() ); } } - - ret |= fprintf( f, " %s\n", - TO_UTF8( comp->GetField( VALUE )->m_Text ) ); + //Print Component Value: + ret |= fprintf( f, " %s\t\t",TO_UTF8( comp->GetField( VALUE )->m_Text ) ); + + //Show Seq Spec on same line as component using line-comment ";": + for(int jj=0;jj"); + } + //Next Netlist line record: + ret |= fprintf( f, "\n"); } } - m_SortedComponentPinList.clear(); - - // Print texts starting with [+]pspice or [+]gnucap - nbitems = spiceCommandAtEndFile.GetCount(); - if( nbitems ) - { - ret |= fprintf( f, "\n" ); - spiceCommandAtEndFile.Sort(); - for( int ii = 0; ii < nbitems; ii++ ) - { - spiceCommandAtEndFile[ii].Remove( 0, +BUFYPOS_LEN ); - spiceCommandAtEndFile[ii].Trim( true ); - spiceCommandAtEndFile[ii].Trim( false ); - ret |= fprintf( f, "%s\n", TO_UTF8( spiceCommandAtEndFile[ii] ) ); - } - } - - ret |= fprintf( f, "\n.end\n" ); - + m_SortedComponentPinList.clear(); + + // Print texts starting with [+]pspice or [+]gnucap + nbitems = spiceCommandAtEndFile.GetCount(); + if( nbitems ) + { + ret |= fprintf( f, "\n" ); + spiceCommandAtEndFile.Sort(); + for( int ii = 0; ii < nbitems; ii++ ) + { + spiceCommandAtEndFile[ii].Remove( 0, +BUFYPOS_LEN ); + spiceCommandAtEndFile[ii].Trim( true ); + spiceCommandAtEndFile[ii].Trim( false ); + ret |= fprintf( f, "%s\n", TO_UTF8( spiceCommandAtEndFile[ii] ) ); + } + } + + ret |= fprintf( f, "\n.end\n" ); + return ret >= 0; -} +} + bool EXPORT_HELP::WriteNetListPCBNEW( FILE* f, bool with_pcbnew )