2007-06-05 12:10:51 +00:00
|
|
|
|
/*******************************************************/
|
|
|
|
|
/* Module de generation de la Netliste , selon Formats */
|
|
|
|
|
/*******************************************************/
|
|
|
|
|
|
|
|
|
|
#include "fctsys.h"
|
|
|
|
|
#include "gr_basic.h"
|
|
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
|
#include "program.h"
|
|
|
|
|
#include "libcmp.h"
|
|
|
|
|
#include "general.h"
|
|
|
|
|
#include "netlist.h"
|
|
|
|
|
|
|
|
|
|
#include "protos.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Routines locales */
|
|
|
|
|
static void Write_GENERIC_NetList(WinEDA_SchematicFrame * frame, const wxString & FullFileName);
|
|
|
|
|
static void WriteNetListPCBNEW(WinEDA_SchematicFrame * frame, FILE *f,
|
|
|
|
|
bool with_pcbnew);
|
|
|
|
|
static void WriteNetListCADSTAR(WinEDA_SchematicFrame * frame, FILE *f);
|
|
|
|
|
static void WriteListOfNetsCADSTAR( FILE * f, ObjetNetListStruct *ObjNet );
|
|
|
|
|
static void WriteNetListPspice(WinEDA_SchematicFrame * frame, FILE *f, bool use_netnames);
|
|
|
|
|
|
|
|
|
|
static void WriteGENERICListOfNets( FILE * f, ObjetNetListStruct *ObjNet );
|
|
|
|
|
static void AddPinToComponentPinList(EDA_SchComponentStruct *Component,
|
|
|
|
|
LibDrawPin *PinEntry);
|
|
|
|
|
static void FindOthersUnits(EDA_SchComponentStruct *Component );
|
|
|
|
|
static int SortPinsByNum(ObjetNetListStruct **Pin1, ObjetNetListStruct **Pin2);
|
|
|
|
|
static void EraseDuplicatePins(ObjetNetListStruct **TabPin, int NbrPin);
|
|
|
|
|
|
|
|
|
|
static void ClearUsedFlags(WinEDA_SchematicFrame * frame);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Variable locales */
|
|
|
|
|
static int s_SortedPinCount;
|
|
|
|
|
static ObjetNetListStruct **s_SortedComponentPinList;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
void WriteNetList(WinEDA_SchematicFrame * frame, const wxString & FileNameNL,
|
|
|
|
|
bool use_netnames)
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Create the netlist file ( Format is given by g_NetFormat )
|
|
|
|
|
bool use_netnames is used only for Spice netlist
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
FILE *f = NULL;
|
|
|
|
|
|
|
|
|
|
if ( g_NetFormat < NET_TYPE_CUSTOM1 )
|
|
|
|
|
{
|
|
|
|
|
if ((f = wxFopen(FileNameNL, wxT("wt"))) == NULL)
|
|
|
|
|
{
|
|
|
|
|
wxString msg = _("Failed to create file ") + FileNameNL;
|
|
|
|
|
DisplayError(frame, msg);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wxBusyCursor Busy;
|
|
|
|
|
|
|
|
|
|
switch ( g_NetFormat )
|
|
|
|
|
{
|
|
|
|
|
case NET_TYPE_PCBNEW :
|
|
|
|
|
WriteNetListPCBNEW(frame, f, TRUE);
|
|
|
|
|
fclose(f);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NET_TYPE_ORCADPCB2 :
|
|
|
|
|
WriteNetListPCBNEW(frame, f, FALSE);
|
|
|
|
|
fclose(f);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NET_TYPE_CADSTAR :
|
|
|
|
|
WriteNetListCADSTAR(frame, f);
|
|
|
|
|
fclose(f);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NET_TYPE_SPICE :
|
|
|
|
|
WriteNetListPspice(frame, f, use_netnames);
|
|
|
|
|
fclose(f);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NET_TYPE_CUSTOM1 :
|
|
|
|
|
case NET_TYPE_CUSTOM2 :
|
|
|
|
|
case NET_TYPE_CUSTOM3 :
|
|
|
|
|
case NET_TYPE_CUSTOM4 :
|
|
|
|
|
case NET_TYPE_CUSTOM5 :
|
|
|
|
|
case NET_TYPE_CUSTOM6 :
|
|
|
|
|
case NET_TYPE_CUSTOM7 :
|
|
|
|
|
case NET_TYPE_CUSTOM8 :
|
|
|
|
|
Write_GENERIC_NetList(frame, FileNameNL);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
DisplayError(frame, wxT("WriteNetList() err: Unknown Netlist Format"));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
static EDA_SchComponentStruct * FindNextComponentAndCreatPinList(
|
|
|
|
|
EDA_BaseStruct * DrawList)
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
/* Find a "suitable" component from the DrawList
|
|
|
|
|
build its pin list s_SortedComponentPinList.
|
|
|
|
|
The list is sorted by pin num
|
|
|
|
|
A suitable component is a "new" real component (power symbols are not considered)
|
|
|
|
|
|
|
|
|
|
alloc memory for s_SortedComponentPinList if s_SortedComponentPinList == NULL
|
|
|
|
|
Must be deallocated by the user
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
EDA_SchComponentStruct * Component = NULL;
|
|
|
|
|
EDA_LibComponentStruct *Entry;
|
|
|
|
|
LibEDA_BaseStruct *DEntry;
|
|
|
|
|
|
|
|
|
|
s_SortedPinCount = 0;
|
|
|
|
|
|
|
|
|
|
for ( ; DrawList != NULL; DrawList = DrawList->Next() )
|
|
|
|
|
{
|
|
|
|
|
if ( DrawList->m_StructType != DRAW_LIB_ITEM_STRUCT_TYPE ) continue;
|
|
|
|
|
Component = (EDA_SchComponentStruct *) DrawList;
|
|
|
|
|
|
|
|
|
|
/* already tested ? : */
|
|
|
|
|
if( Component->m_FlagControlMulti == 1 ) continue; /* yes */
|
|
|
|
|
|
|
|
|
|
Entry = FindLibPart(Component->m_ChipName.GetData(), wxEmptyString, FIND_ROOT);
|
|
|
|
|
if( Entry == NULL) continue;
|
|
|
|
|
|
|
|
|
|
/* Power symbol and other component which have the reference starting by
|
|
|
|
|
"#" are not included in netlist (pseudo components) */
|
|
|
|
|
if( Component->m_Field[REFERENCE].m_Text[0] == '#' ) continue;
|
|
|
|
|
|
|
|
|
|
/* Create the pin table for this component */
|
|
|
|
|
int ii = sizeof(ObjetNetListStruct) * MAXPIN;
|
|
|
|
|
if ( s_SortedComponentPinList == NULL )
|
|
|
|
|
s_SortedComponentPinList = (ObjetNetListStruct **) MyMalloc(ii);
|
|
|
|
|
memset(s_SortedComponentPinList, 0 , ii);
|
|
|
|
|
|
|
|
|
|
DEntry = Entry->m_Drawings;
|
|
|
|
|
for ( ;DEntry != NULL; DEntry = DEntry->Next())
|
|
|
|
|
{
|
|
|
|
|
if ( DEntry->m_StructType != COMPONENT_PIN_DRAW_TYPE) continue;
|
|
|
|
|
if( DEntry->m_Unit &&
|
|
|
|
|
(DEntry->m_Unit != Component->m_Multi) ) continue;
|
|
|
|
|
if( DEntry->m_Convert &&
|
|
|
|
|
(DEntry->m_Convert != Component->m_Convert)) continue;
|
|
|
|
|
{
|
|
|
|
|
AddPinToComponentPinList(Component, (LibDrawPin*)DEntry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Component->m_FlagControlMulti = 1;
|
|
|
|
|
|
|
|
|
|
if (Entry->m_UnitCount > 1) FindOthersUnits(Component);
|
|
|
|
|
|
|
|
|
|
/* Tri sur le numero de Pin de TabListePin */
|
|
|
|
|
qsort(s_SortedComponentPinList, s_SortedPinCount, sizeof(ObjetNetListStruct*),
|
|
|
|
|
(int (*)(const void *, const void *)) SortPinsByNum);
|
|
|
|
|
|
|
|
|
|
/* Elimination des Pins redondantes du s_SortedComponentPinList */
|
|
|
|
|
EraseDuplicatePins(s_SortedComponentPinList, s_SortedPinCount);
|
|
|
|
|
|
|
|
|
|
return Component;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**************************************************************************************/
|
|
|
|
|
static wxString ReturnPinNetName(ObjetNetListStruct *Pin,
|
|
|
|
|
const wxString& DefaultFormatNetname)
|
|
|
|
|
/**************************************************************************************/
|
|
|
|
|
/* Return the net name for the pin Pin.
|
|
|
|
|
Net name is:
|
|
|
|
|
"?" if pin not connected
|
|
|
|
|
"netname" for global net (like gnd, vcc ..
|
|
|
|
|
"netname_sheetnumber" for the usual nets
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
int netcode = Pin->m_NetCode;
|
|
|
|
|
wxString NetName;
|
|
|
|
|
|
|
|
|
|
if( (netcode == 0 ) || ( Pin->m_FlagOfConnection != CONNECT ) )
|
|
|
|
|
{
|
|
|
|
|
return NetName;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int jj;
|
|
|
|
|
for (jj = 0; jj < g_NbrObjNet; jj++)
|
|
|
|
|
{
|
|
|
|
|
if( g_TabObjNet[jj].m_NetCode != netcode) continue;
|
|
|
|
|
if( ( g_TabObjNet[jj].m_Type != NET_GLOBLABEL) &&
|
|
|
|
|
( g_TabObjNet[jj].m_Type != NET_LABEL) &&
|
|
|
|
|
( g_TabObjNet[jj].m_Type != NET_PINLABEL) ) continue;
|
|
|
|
|
|
|
|
|
|
NetName = * g_TabObjNet[jj].m_Label;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( ! NetName.IsEmpty() )
|
|
|
|
|
{
|
|
|
|
|
if( g_TabObjNet[jj].m_Type != NET_PINLABEL )
|
|
|
|
|
NetName << wxT("_") << g_TabObjNet[jj].m_SheetNumber;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
NetName.Printf(DefaultFormatNetname.GetData(), netcode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NetName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
|
void Write_GENERIC_NetList(WinEDA_SchematicFrame * frame,
|
|
|
|
|
const wxString & FullFileName)
|
|
|
|
|
/***********************************************************************/
|
|
|
|
|
/* Create a generic netlist, and call an external netlister
|
|
|
|
|
to change the netlist syntax and create the file
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
wxString Line, FootprintName;
|
|
|
|
|
BASE_SCREEN *CurrScreen;
|
|
|
|
|
EDA_BaseStruct *DrawList;
|
|
|
|
|
EDA_SchComponentStruct *Component;
|
|
|
|
|
wxString netname;
|
|
|
|
|
int ii;
|
|
|
|
|
FILE * tmpfile;
|
|
|
|
|
wxString TmpFullFileName = FullFileName;
|
|
|
|
|
|
|
|
|
|
ChangeFileNameExt(TmpFullFileName, wxT(".tmp"));
|
|
|
|
|
|
|
|
|
|
if ((tmpfile = wxFopen(TmpFullFileName, wxT("wt"))) == NULL)
|
|
|
|
|
{
|
|
|
|
|
wxString msg = _("Failed to create file ") + TmpFullFileName;
|
|
|
|
|
DisplayError(frame, msg);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ClearUsedFlags(frame); /* Reset the flags FlagControlMulti in all schematic files*/
|
|
|
|
|
fprintf( tmpfile, "$BeginNetlist\n" );
|
|
|
|
|
|
|
|
|
|
/* Create netlist module section */
|
|
|
|
|
fprintf( tmpfile, "$BeginComponentList\n" );
|
|
|
|
|
for(CurrScreen = ScreenSch; CurrScreen != NULL; CurrScreen = (BASE_SCREEN*)CurrScreen->Pnext )
|
|
|
|
|
{
|
|
|
|
|
for ( DrawList = CurrScreen->EEDrawList; DrawList != NULL; DrawList = DrawList->Pnext )
|
|
|
|
|
{
|
|
|
|
|
DrawList = Component = FindNextComponentAndCreatPinList(DrawList);
|
|
|
|
|
if ( Component == NULL ) break; // No component left
|
|
|
|
|
|
|
|
|
|
FootprintName.Empty();
|
|
|
|
|
if( ! Component->m_Field[FOOTPRINT].IsVoid() )
|
|
|
|
|
{
|
|
|
|
|
FootprintName = Component->m_Field[FOOTPRINT].m_Text;
|
|
|
|
|
FootprintName.Replace(wxT(" "), wxT("_"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf( tmpfile, "\n$BeginComponent\n" );
|
|
|
|
|
fprintf(tmpfile, "TimeStamp=%8.8lX\n", Component->m_TimeStamp);
|
|
|
|
|
fprintf(tmpfile, "Footprint=%s\n", CONV_TO_UTF8(FootprintName));
|
|
|
|
|
Line = wxT("Reference=") + Component->m_Field[REFERENCE].m_Text + wxT("\n");
|
|
|
|
|
Line.Replace(wxT(" "), wxT("_"));
|
|
|
|
|
fprintf(tmpfile, CONV_TO_UTF8(Line));
|
|
|
|
|
|
|
|
|
|
Line = Component->m_Field[VALUE].m_Text;
|
|
|
|
|
Line.Replace( wxT(" "), wxT("_"));
|
|
|
|
|
fprintf(tmpfile, "Value=%s\n", CONV_TO_UTF8(Line));
|
|
|
|
|
|
|
|
|
|
Line = Component->m_ChipName;
|
|
|
|
|
Line.Replace(wxT(" "), wxT("_"));
|
|
|
|
|
fprintf(tmpfile, "Libref=%s\n", CONV_TO_UTF8(Line));
|
|
|
|
|
|
|
|
|
|
// Write pin list:
|
|
|
|
|
fprintf( tmpfile, "$BeginPinList\n" );
|
|
|
|
|
for (ii = 0; ii < s_SortedPinCount; ii++)
|
|
|
|
|
{
|
|
|
|
|
ObjetNetListStruct *Pin = s_SortedComponentPinList[ii];
|
|
|
|
|
if( ! Pin ) continue;
|
|
|
|
|
netname = ReturnPinNetName(Pin, wxT("$-%.6d"));
|
|
|
|
|
if ( netname.IsEmpty() ) netname = wxT("?");
|
|
|
|
|
fprintf( tmpfile,"%.4s=%s\n",(char *)&Pin->m_PinNum,
|
|
|
|
|
CONV_TO_UTF8(netname));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf( tmpfile, "$EndPinList\n" );
|
|
|
|
|
fprintf( tmpfile, "$EndComponent\n" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MyFree(s_SortedComponentPinList);
|
|
|
|
|
s_SortedComponentPinList = NULL;
|
|
|
|
|
|
|
|
|
|
fprintf( tmpfile, "$EndComponentList\n" );
|
|
|
|
|
|
|
|
|
|
fprintf( tmpfile, "\n$BeginNets\n" );
|
|
|
|
|
WriteGENERICListOfNets( tmpfile, g_TabObjNet );
|
|
|
|
|
fprintf( tmpfile, "$EndNets\n" );
|
|
|
|
|
fprintf( tmpfile, "\n$EndNetlist\n" );
|
|
|
|
|
fclose(tmpfile);
|
|
|
|
|
|
|
|
|
|
// Call the external module (plug in )
|
|
|
|
|
|
|
|
|
|
if ( g_NetListerCommandLine.IsEmpty() ) return;
|
|
|
|
|
|
|
|
|
|
wxString CommandFile;
|
|
|
|
|
if ( wxIsAbsolutePath(g_NetListerCommandLine) )
|
|
|
|
|
CommandFile = g_NetListerCommandLine;
|
|
|
|
|
else CommandFile = FindKicadFile(g_NetListerCommandLine);
|
|
|
|
|
|
|
|
|
|
CommandFile += wxT(" ") + TmpFullFileName;
|
|
|
|
|
CommandFile += wxT(" ") + FullFileName;
|
|
|
|
|
|
|
|
|
|
wxExecute(CommandFile, wxEXEC_SYNC);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************/
|
|
|
|
|
static void ClearUsedFlags(WinEDA_SchematicFrame * frame)
|
|
|
|
|
/********************************************************/
|
|
|
|
|
/* Clear flag FlagControlMulti, used in netlist generation */
|
|
|
|
|
{
|
|
|
|
|
SCH_SCREEN *screen;
|
|
|
|
|
EDA_BaseStruct *DrawList;
|
|
|
|
|
|
2007-05-06 16:03:28 +00:00
|
|
|
|
EDA_ScreenList ScreenList(NULL);
|
|
|
|
|
for ( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
{
|
|
|
|
|
DrawList = screen->EEDrawList;
|
|
|
|
|
while ( DrawList )
|
|
|
|
|
{
|
|
|
|
|
if( DrawList->m_StructType == DRAW_LIB_ITEM_STRUCT_TYPE)
|
|
|
|
|
{
|
|
|
|
|
EDA_SchComponentStruct * Component = (EDA_SchComponentStruct *) DrawList;
|
|
|
|
|
Component->m_FlagControlMulti = 0;
|
|
|
|
|
}
|
|
|
|
|
DrawList = DrawList->Pnext;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*************************************************************/
|
|
|
|
|
static void WriteNetListPspice(WinEDA_SchematicFrame * frame, FILE *f,
|
|
|
|
|
bool use_netnames)
|
|
|
|
|
/*************************************************************/
|
|
|
|
|
/* Routine de generation du fichier netliste ( Format PSPICE )
|
|
|
|
|
si use_netnames = TRUE
|
|
|
|
|
les nodes sont identifies par le netname
|
|
|
|
|
sinon les nodes sont identifies par le netnumber
|
|
|
|
|
|
|
|
|
|
tous les textes graphiques commen<EFBFBD>ant par [.-+]pspice ou [.-+]gnucap
|
|
|
|
|
sont consid<EFBFBD>r<EFBFBD>s comme des commandes a placer dans la netliste
|
|
|
|
|
[.-]pspice ou gnucap sont en debut
|
|
|
|
|
+pspice et +gnucap sont en fin de netliste
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
char Line[1024];
|
|
|
|
|
SCH_SCREEN *screen;
|
|
|
|
|
EDA_BaseStruct *DrawList;
|
|
|
|
|
EDA_SchComponentStruct *Component;
|
|
|
|
|
int ii, nbitems;
|
|
|
|
|
wxString text;
|
|
|
|
|
wxArrayString SpiceCommandAtBeginFile, SpiceCommandAtEndFile;
|
|
|
|
|
wxString msg;
|
|
|
|
|
#define BUFYPOS_LEN 4
|
|
|
|
|
wxChar bufnum[BUFYPOS_LEN+1];
|
|
|
|
|
|
|
|
|
|
DateAndTime(Line);
|
|
|
|
|
fprintf( f, "* %s (Spice format) creation date: %s\n\n", NETLIST_HEAD_STRING, Line );
|
|
|
|
|
|
|
|
|
|
/* Create text list starting by [.-]pspice , or [.-]gnucap (simulator commands) */
|
|
|
|
|
/* and create text list starting by [+]pspice , or [+]gnucap (simulator commands) */
|
|
|
|
|
bufnum[BUFYPOS_LEN] = 0;
|
2007-05-06 16:03:28 +00:00
|
|
|
|
EDA_ScreenList ScreenList(NULL);
|
|
|
|
|
for ( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
{
|
|
|
|
|
for ( DrawList = screen->EEDrawList; DrawList != NULL; DrawList = DrawList->Pnext )
|
|
|
|
|
{
|
|
|
|
|
wxChar ident;
|
|
|
|
|
if ( DrawList->m_StructType != DRAW_TEXT_STRUCT_TYPE ) continue;
|
|
|
|
|
#define DRAWTEXT ((DrawTextStruct *) DrawList)
|
|
|
|
|
text = DRAWTEXT->m_Text; if ( text.IsEmpty() ) continue;
|
|
|
|
|
ident = text.GetChar(0);
|
|
|
|
|
if ( ident != '.' && ident != '-' && ident != '+' ) continue;
|
|
|
|
|
text.Remove(0,1); //Remove the first char.
|
|
|
|
|
text.Remove(6); //text contains 6 char.
|
|
|
|
|
if( ( text == wxT("pspice") ) || ( text == wxT("gnucap") ) )
|
|
|
|
|
{
|
|
|
|
|
/* Put the Y position as an ascii string, for sort by vertical position,
|
|
|
|
|
using usual sort string by alphabetic value */
|
|
|
|
|
int ypos = DRAWTEXT->m_Pos.y;
|
|
|
|
|
for ( ii = 0; ii < BUFYPOS_LEN; ii++ )
|
|
|
|
|
{
|
|
|
|
|
bufnum[BUFYPOS_LEN-1-ii] = (ypos & 63) + ' '; ypos >>= 6;
|
|
|
|
|
}
|
|
|
|
|
text = DRAWTEXT->m_Text.AfterFirst( ' ');
|
|
|
|
|
msg.Printf( wxT("%s %s"),bufnum, text.GetData()); // First BUFYPOS_LEN char are the Y position
|
|
|
|
|
if ( ident == '+' ) SpiceCommandAtEndFile.Add(msg);
|
|
|
|
|
else SpiceCommandAtBeginFile.Add(msg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Print texts starting by [.-]pspice , ou [.-]gnucap (of course, without the Y position string)*/
|
|
|
|
|
nbitems = SpiceCommandAtBeginFile.GetCount();
|
|
|
|
|
if ( nbitems )
|
|
|
|
|
{
|
|
|
|
|
SpiceCommandAtBeginFile.Sort();
|
|
|
|
|
for(ii= 0; ii < nbitems; ii++ )
|
|
|
|
|
{
|
|
|
|
|
SpiceCommandAtBeginFile[ii].Remove(0, BUFYPOS_LEN);
|
|
|
|
|
SpiceCommandAtBeginFile[ii].Trim(TRUE);
|
|
|
|
|
SpiceCommandAtBeginFile[ii].Trim(FALSE);
|
|
|
|
|
fprintf( f, "%s\n", CONV_TO_UTF8(SpiceCommandAtBeginFile[ii]) );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fprintf( f, "\n" );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Create component list */
|
|
|
|
|
ClearUsedFlags(frame); /* Reset the flags FlagControlMulti in all schematic files*/
|
2007-05-06 16:03:28 +00:00
|
|
|
|
for ( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
{
|
|
|
|
|
for( DrawList = screen->EEDrawList; DrawList != NULL; DrawList = DrawList->Pnext )
|
|
|
|
|
{
|
|
|
|
|
DrawList = Component = FindNextComponentAndCreatPinList(DrawList);
|
|
|
|
|
if ( Component == NULL ) break;
|
|
|
|
|
|
|
|
|
|
fprintf(f, "%s ", CONV_TO_UTF8(Component->m_Field[REFERENCE].m_Text));
|
|
|
|
|
|
|
|
|
|
// Write pin list:
|
|
|
|
|
for (ii = 0; ii < s_SortedPinCount; ii++)
|
|
|
|
|
{
|
|
|
|
|
ObjetNetListStruct *Pin = s_SortedComponentPinList[ii];
|
|
|
|
|
if( ! Pin ) continue;
|
|
|
|
|
wxString NetName = ReturnPinNetName(Pin, wxT("N-%.6d"));
|
|
|
|
|
if ( NetName.IsEmpty() ) NetName = wxT("?");
|
|
|
|
|
if( use_netnames) fprintf( f," %s", CONV_TO_UTF8(NetName));
|
|
|
|
|
else // Use number for net names (with net number = 0 for "GND"
|
|
|
|
|
{
|
|
|
|
|
// NetName = "0" is "GND" net for Spice
|
|
|
|
|
if( NetName == wxT("0") || NetName == wxT("GND") )
|
|
|
|
|
fprintf( f," 0");
|
|
|
|
|
else fprintf( f," %d", Pin->m_NetCode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fprintf(f, " %s\n", CONV_TO_UTF8(Component->m_Field[VALUE].m_Text));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MyFree(s_SortedComponentPinList);
|
|
|
|
|
s_SortedComponentPinList = NULL;
|
|
|
|
|
|
|
|
|
|
/* Print texts starting by [+]pspice , ou [+]gnucap */
|
|
|
|
|
nbitems = SpiceCommandAtEndFile.GetCount();
|
|
|
|
|
if ( nbitems )
|
|
|
|
|
{
|
|
|
|
|
fprintf( f, "\n" );
|
|
|
|
|
SpiceCommandAtEndFile.Sort();
|
|
|
|
|
for(ii= 0; ii < nbitems; ii++ )
|
|
|
|
|
{
|
|
|
|
|
SpiceCommandAtEndFile[ii].Remove(0, + BUFYPOS_LEN);
|
|
|
|
|
SpiceCommandAtEndFile[ii].Trim(TRUE);
|
|
|
|
|
SpiceCommandAtEndFile[ii].Trim(FALSE);
|
|
|
|
|
fprintf( f, "%s\n", CONV_TO_UTF8(SpiceCommandAtEndFile[ii]));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf( f, "\n.end\n" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************/
|
|
|
|
|
static void WriteNetListPCBNEW(WinEDA_SchematicFrame * frame, FILE *f, bool with_pcbnew)
|
|
|
|
|
/*****************************************************************************************/
|
|
|
|
|
/* Routine de generation du fichier netliste ( Format ORCAD PCB 2 ameliore )
|
|
|
|
|
si with_pcbnew = FALSE
|
|
|
|
|
format PCBNEW (OrcadPcb2 + commentaires et liste des nets)
|
|
|
|
|
si with_pcbnew = FALSE
|
|
|
|
|
Format ORCADPCB2 strict
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
wxString Line, FootprintName;
|
|
|
|
|
char Buf[256];
|
|
|
|
|
SCH_SCREEN *CurrScreen;
|
|
|
|
|
EDA_BaseStruct *DrawList;
|
|
|
|
|
EDA_SchComponentStruct *Component;
|
|
|
|
|
int ii;
|
|
|
|
|
EDA_SchComponentStruct ** CmpList = NULL;
|
|
|
|
|
int CmpListCount = 0, CmpListSize = 1000;
|
|
|
|
|
|
|
|
|
|
DateAndTime(Buf);
|
|
|
|
|
if ( with_pcbnew )
|
|
|
|
|
fprintf( f, "# %s created %s\n(\n", NETLIST_HEAD_STRING, Buf);
|
|
|
|
|
else fprintf( f, "( { %s created %s }\n", NETLIST_HEAD_STRING, Buf );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Create netlist module section */
|
|
|
|
|
ClearUsedFlags(frame); /* Reset the flags FlagControlMulti in all schematic files*/
|
|
|
|
|
|
2007-05-06 16:03:28 +00:00
|
|
|
|
EDA_ScreenList ScreenList(NULL);
|
|
|
|
|
for ( CurrScreen = ScreenList.GetFirst(); CurrScreen != NULL; CurrScreen = ScreenList.GetNext() )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
{
|
|
|
|
|
for ( DrawList = CurrScreen->EEDrawList; DrawList != NULL; DrawList = DrawList->Pnext )
|
|
|
|
|
{
|
|
|
|
|
DrawList = Component = FindNextComponentAndCreatPinList(DrawList);
|
|
|
|
|
if ( Component == NULL ) break;
|
|
|
|
|
|
|
|
|
|
/* Get the Component FootprintFilter and put the component in CmpList if filter is not void */
|
|
|
|
|
EDA_LibComponentStruct *Entry;
|
|
|
|
|
if( (Entry = FindLibPart(Component->m_ChipName.GetData(),wxEmptyString,FIND_ROOT)) != NULL)
|
|
|
|
|
{
|
|
|
|
|
if ( Entry->m_FootprintList.GetCount() != 0 ) /* Put in list */
|
|
|
|
|
{
|
|
|
|
|
if ( CmpList == NULL )
|
|
|
|
|
CmpList = (EDA_SchComponentStruct **) MyZMalloc(sizeof(EDA_SchComponentStruct *) * CmpListSize);
|
|
|
|
|
if ( CmpListCount >= CmpListSize )
|
|
|
|
|
{
|
|
|
|
|
CmpListSize += 1000;
|
|
|
|
|
CmpList = (EDA_SchComponentStruct **) realloc(CmpList, sizeof(EDA_SchComponentStruct *) * CmpListSize);
|
|
|
|
|
}
|
|
|
|
|
CmpList[CmpListCount] = Component;
|
|
|
|
|
CmpListCount++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( ! Component->m_Field[FOOTPRINT].IsVoid() )
|
|
|
|
|
{
|
|
|
|
|
FootprintName = Component->m_Field[FOOTPRINT].m_Text;
|
|
|
|
|
FootprintName.Replace( wxT(" "), wxT("_") );
|
|
|
|
|
}
|
|
|
|
|
else FootprintName = wxT("$noname");
|
|
|
|
|
|
|
|
|
|
Line = Component->m_Field[REFERENCE].m_Text;
|
|
|
|
|
Line.Replace( wxT(" "), wxT("_") );
|
|
|
|
|
fprintf(f, " ( %8.8lX %s",
|
|
|
|
|
Component->m_TimeStamp,
|
|
|
|
|
CONV_TO_UTF8(FootprintName));
|
|
|
|
|
fprintf(f, " %s", CONV_TO_UTF8(Line));
|
|
|
|
|
|
|
|
|
|
Line = Component->m_Field[VALUE].m_Text;
|
|
|
|
|
Line.Replace( wxT(" "), wxT("_") );
|
|
|
|
|
fprintf(f, " %s", CONV_TO_UTF8(Line));
|
|
|
|
|
|
|
|
|
|
if ( with_pcbnew ) // Add the lib name for this component
|
|
|
|
|
{
|
|
|
|
|
Line = Component->m_ChipName;
|
|
|
|
|
Line.Replace( wxT(" "), wxT("_") );
|
|
|
|
|
fprintf(f, " {Lib=%s}", CONV_TO_UTF8(Line));
|
|
|
|
|
}
|
|
|
|
|
fprintf(f, "\n");
|
|
|
|
|
|
|
|
|
|
// Write pin list:
|
|
|
|
|
for (ii = 0; ii < s_SortedPinCount; ii++)
|
|
|
|
|
{
|
|
|
|
|
ObjetNetListStruct *Pin = s_SortedComponentPinList[ii];
|
|
|
|
|
if( ! Pin ) continue;
|
|
|
|
|
wxString netname = ReturnPinNetName(Pin, wxT("N-%.6d"));
|
|
|
|
|
if ( netname.IsEmpty() ) netname = wxT(" ?");
|
|
|
|
|
fprintf( f," ( %4.4s %s )\n",(char *)&Pin->m_PinNum,
|
|
|
|
|
CONV_TO_UTF8(netname));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(f, " )\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fprintf( f, ")\n*\n");
|
|
|
|
|
|
|
|
|
|
MyFree(s_SortedComponentPinList);
|
|
|
|
|
s_SortedComponentPinList = NULL;
|
|
|
|
|
|
|
|
|
|
/* Write the allowed footprint list for each component */
|
|
|
|
|
if ( with_pcbnew && CmpList)
|
|
|
|
|
{
|
|
|
|
|
fprintf( f, "{ Allowed footprints by component:\n" );
|
|
|
|
|
EDA_LibComponentStruct *Entry;
|
|
|
|
|
for ( ii = 0; ii < CmpListCount; ii ++ )
|
|
|
|
|
{
|
|
|
|
|
Component = CmpList[ii];
|
|
|
|
|
Entry = FindLibPart(Component->m_ChipName.GetData(),wxEmptyString,FIND_ROOT);
|
|
|
|
|
Line = Component->m_Field[REFERENCE].m_Text;
|
|
|
|
|
Line.Replace( wxT(" "), wxT("_") );
|
|
|
|
|
fprintf(f, "$component %s\n", CONV_TO_UTF8(Line));
|
|
|
|
|
/* Write the footprint list */
|
|
|
|
|
for ( unsigned int jj = 0; jj < Entry->m_FootprintList.GetCount(); jj ++ )
|
|
|
|
|
{
|
|
|
|
|
fprintf(f, " %s\n", CONV_TO_UTF8(Entry->m_FootprintList[jj]));
|
|
|
|
|
}
|
|
|
|
|
fprintf(f, "$endlist\n");
|
|
|
|
|
}
|
|
|
|
|
fprintf(f, "$endfootprintlist\n}\n");
|
|
|
|
|
}
|
|
|
|
|
if ( CmpList ) free(CmpList);
|
|
|
|
|
|
|
|
|
|
if ( with_pcbnew )
|
|
|
|
|
{
|
|
|
|
|
fprintf( f, "{ Pin List by Nets\n" );
|
|
|
|
|
WriteGENERICListOfNets( f, g_TabObjNet );
|
|
|
|
|
fprintf( f, "}\n" );
|
|
|
|
|
fprintf( f, "#End\n" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************************/
|
|
|
|
|
static void AddPinToComponentPinList( EDA_SchComponentStruct *Component, LibDrawPin *Pin)
|
|
|
|
|
/*************************************************************************************/
|
|
|
|
|
/* Add a new pin description in the pin list s_SortedComponentPinList
|
|
|
|
|
a pin description is a pointer to the corresponding structure
|
|
|
|
|
created by BuildNetList() in the table g_TabObjNet
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
int ii;
|
|
|
|
|
|
|
|
|
|
/* Search the PIN description for Pin in g_TabObjNet*/
|
|
|
|
|
for (ii = 0; ii < g_NbrObjNet; ii++)
|
|
|
|
|
{
|
|
|
|
|
if ( g_TabObjNet[ii].m_Type != NET_PIN) continue;
|
|
|
|
|
if ( g_TabObjNet[ii].m_Link != Component) continue;
|
|
|
|
|
if ( g_TabObjNet[ii].m_PinNum != Pin->m_PinNum) continue;
|
|
|
|
|
{
|
|
|
|
|
s_SortedComponentPinList[s_SortedPinCount] = & g_TabObjNet[ii];
|
|
|
|
|
s_SortedPinCount++;
|
|
|
|
|
if (s_SortedPinCount >= MAXPIN)
|
|
|
|
|
{
|
|
|
|
|
/* Log message for Internal error */
|
|
|
|
|
DisplayError(NULL, wxT("AddPinToComponentPinList err: MAXPIN reached")); return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************************/
|
|
|
|
|
static void EraseDuplicatePins(ObjetNetListStruct **TabPin, int NbrPin)
|
|
|
|
|
/**********************************************************************/
|
|
|
|
|
/*
|
|
|
|
|
Routine qui elimine les Pins de meme Numero de la liste des objets
|
|
|
|
|
(Liste des Pins d'un boitier) passee en entree
|
|
|
|
|
Ces pins redondantes proviennent des pins (alims... ) communes a plusieurs
|
|
|
|
|
elements d'un boitier a multiple parts.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
int ii, jj;
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < NbrPin-1; ii++)
|
|
|
|
|
{
|
|
|
|
|
if( TabPin[ii] == NULL) continue; /* Deja supprime */
|
|
|
|
|
if( TabPin[ii]->m_PinNum != TabPin[ii+1]->m_PinNum) continue;
|
|
|
|
|
/* 2 Pins doublees */
|
|
|
|
|
for( jj = ii+1; jj < NbrPin ; jj++ )
|
|
|
|
|
{
|
|
|
|
|
if( TabPin[ii]->m_PinNum != TabPin[jj]->m_PinNum) break;
|
|
|
|
|
TabPin[jj] = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************************/
|
|
|
|
|
static void FindOthersUnits(EDA_SchComponentStruct *Component )
|
|
|
|
|
/**********************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Recherche les autres parts du boitier auquel appartient la part Component,
|
|
|
|
|
pour les boitiers a parts multiples.
|
|
|
|
|
Appelle AddPinToComponentPinList() pour classer les pins des parts trouvees
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
EDA_BaseStruct *DrawList;
|
|
|
|
|
EDA_SchComponentStruct *Component2;
|
|
|
|
|
EDA_LibComponentStruct *Entry;
|
|
|
|
|
LibEDA_BaseStruct *DEntry;
|
|
|
|
|
SCH_SCREEN * screen;
|
|
|
|
|
|
2007-05-06 16:03:28 +00:00
|
|
|
|
EDA_ScreenList ScreenList(NULL);
|
|
|
|
|
for ( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
{
|
|
|
|
|
DrawList = screen->EEDrawList;
|
|
|
|
|
while ( DrawList )
|
|
|
|
|
{
|
|
|
|
|
switch( DrawList->m_StructType )
|
|
|
|
|
{
|
|
|
|
|
case DRAW_LIB_ITEM_STRUCT_TYPE :
|
|
|
|
|
Component2 = (EDA_SchComponentStruct *) DrawList;
|
|
|
|
|
|
|
|
|
|
if ( Component2->m_FlagControlMulti == 1 ) break;
|
|
|
|
|
|
|
|
|
|
if ( Component2->m_Field[REFERENCE].m_Text.CmpNoCase(
|
|
|
|
|
Component->m_Field[REFERENCE].m_Text) != 0 )
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
Entry = FindLibPart(Component2->m_ChipName.GetData(), wxEmptyString, FIND_ROOT);
|
|
|
|
|
if( Entry == NULL) break;
|
|
|
|
|
if( Component2->m_Field[REFERENCE].m_Text[0] == '#' ) break;
|
|
|
|
|
|
|
|
|
|
if (Entry->m_Drawings != NULL)
|
|
|
|
|
{
|
|
|
|
|
DEntry = Entry->m_Drawings;
|
|
|
|
|
for ( ;DEntry != NULL; DEntry = DEntry->Next())
|
|
|
|
|
{
|
|
|
|
|
if ( DEntry->m_StructType != COMPONENT_PIN_DRAW_TYPE) continue;
|
|
|
|
|
if( DEntry->m_Unit &&
|
|
|
|
|
(DEntry->m_Unit != Component2->m_Multi) ) continue;
|
|
|
|
|
if( DEntry->m_Convert &&
|
|
|
|
|
(DEntry->m_Convert != Component2->m_Convert)) continue;
|
|
|
|
|
{
|
|
|
|
|
AddPinToComponentPinList(Component2, (LibDrawPin*)DEntry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Component2->m_FlagControlMulti = 1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
DrawList = DrawList->Pnext;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
|
static int SortPinsByNum(ObjetNetListStruct **Pin1, ObjetNetListStruct **Pin2)
|
|
|
|
|
/**************************************************************************/
|
|
|
|
|
/* Routine de comparaison pour le tri des pins par numero croissant
|
|
|
|
|
du tableau des pins s_SortedComponentPinList par qsort()
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
ObjetNetListStruct * Obj1, * Obj2;
|
|
|
|
|
int Num1, Num2;
|
|
|
|
|
char Line[5];
|
|
|
|
|
|
|
|
|
|
Obj1 = *Pin1; Obj2 = *Pin2;
|
|
|
|
|
Num1 = Obj1->m_PinNum; Num2 = Obj2->m_PinNum;
|
|
|
|
|
Line[4] = 0; memcpy(Line, &Num1, 4 ); Num1 = atoi(Line);
|
|
|
|
|
memcpy(Line, &Num2, 4 ); Num2 = atoi(Line);
|
|
|
|
|
return (Num1 - Num2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
|
static void WriteGENERICListOfNets( FILE * f, ObjetNetListStruct *ObjNet )
|
|
|
|
|
/*************************************************************************/
|
|
|
|
|
/* Ecrit dans le fichier f la liste des nets ( classee par NetCodes ), et des
|
|
|
|
|
elements qui y sont connectes
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
int ii, jj;
|
|
|
|
|
int NetCode, LastNetCode = -1;
|
|
|
|
|
int SameNetcodeCount = 0;
|
|
|
|
|
EDA_SchComponentStruct * Cmp;
|
|
|
|
|
wxString NetName, CmpRef;
|
|
|
|
|
wxString NetcodeName;
|
|
|
|
|
char FirstItemInNet[1024];
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < g_NbrObjNet; ii++)
|
|
|
|
|
{
|
|
|
|
|
if( (NetCode = ObjNet[ii].m_NetCode) != LastNetCode ) // New net found, write net id;
|
|
|
|
|
{
|
|
|
|
|
SameNetcodeCount = 0; // Items count for this net
|
|
|
|
|
NetName.Empty();
|
|
|
|
|
for (jj = 0; jj < g_NbrObjNet; jj++) // Find a label (if exists) for this net
|
|
|
|
|
{
|
|
|
|
|
if( ObjNet[jj].m_NetCode != NetCode) continue;
|
|
|
|
|
if( ( ObjNet[jj].m_Type != NET_GLOBLABEL) &&
|
|
|
|
|
( ObjNet[jj].m_Type != NET_LABEL) &&
|
|
|
|
|
( ObjNet[jj].m_Type != NET_PINLABEL) ) continue;
|
|
|
|
|
|
|
|
|
|
NetName = * g_TabObjNet[jj].m_Label; break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NetcodeName.Printf( wxT("Net %d "), NetCode);
|
|
|
|
|
NetcodeName += wxT("\"");
|
|
|
|
|
if( ! NetName.IsEmpty() )
|
|
|
|
|
{
|
|
|
|
|
NetcodeName += NetName;
|
|
|
|
|
if( g_TabObjNet[jj].m_Type != NET_PINLABEL) // usual net name, add it the sheet number
|
|
|
|
|
NetcodeName << wxT("_") << g_TabObjNet[jj].m_SheetNumber;
|
|
|
|
|
}
|
|
|
|
|
NetcodeName += wxT("\"");
|
|
|
|
|
LastNetCode = NetCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( ObjNet[ii].m_Type != NET_PIN ) continue;
|
|
|
|
|
|
|
|
|
|
Cmp = (EDA_SchComponentStruct*) ObjNet[ii].m_Link;
|
|
|
|
|
CmpRef = Cmp->m_Field[REFERENCE].m_Text;
|
|
|
|
|
if ( CmpRef.StartsWith( wxT("#") ) ) continue; // Pseudo component (Like Power symbol)
|
|
|
|
|
|
|
|
|
|
// Print the pin list for this net, if 2 or more items are connected:
|
|
|
|
|
SameNetcodeCount++;
|
|
|
|
|
if ( SameNetcodeCount == 1 ) /* first item for this net found,
|
|
|
|
|
Print this connection, when a second item will be found */
|
|
|
|
|
{
|
|
|
|
|
sprintf(FirstItemInNet, " %s %.4s\n", CONV_TO_UTF8(CmpRef),
|
|
|
|
|
(const char*) & ObjNet[ii].m_PinNum);
|
|
|
|
|
}
|
|
|
|
|
if ( SameNetcodeCount == 2 ) // Second item for this net found, Print the Net name, and the first item
|
|
|
|
|
{
|
|
|
|
|
fprintf( f, "%s\n", CONV_TO_UTF8(NetcodeName));
|
|
|
|
|
fputs( FirstItemInNet, f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( SameNetcodeCount >= 2 )
|
|
|
|
|
fprintf( f, " %s %.4s\n", CONV_TO_UTF8(CmpRef),
|
|
|
|
|
(const char*) & ObjNet[ii].m_PinNum);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Generation des netlistes au format CadStar */
|
|
|
|
|
wxString StartLine( wxT("."));
|
|
|
|
|
|
|
|
|
|
/*********************************************************/
|
|
|
|
|
static void WriteNetListCADSTAR(WinEDA_SchematicFrame * frame, FILE *f)
|
|
|
|
|
/*********************************************************/
|
|
|
|
|
/* Routine de generation du fichier netliste ( Format CADSTAR )
|
|
|
|
|
Entete:
|
|
|
|
|
..HEA
|
|
|
|
|
..TIM 2004 07 29 16 22 17
|
|
|
|
|
..APP "Cadstar RINF Output - Version 6.0.2.3"
|
|
|
|
|
..UNI INCH 1000.0 in
|
|
|
|
|
..TYP FULL
|
|
|
|
|
|
|
|
|
|
liste des composants:
|
|
|
|
|
..ADD_COM X1 "CNT D41612 (48PTS MC CONTOUR)"
|
|
|
|
|
..ADD_COM U2 "74HCT245D" "74HCT245D"
|
|
|
|
|
|
|
|
|
|
Connexions:
|
|
|
|
|
..ADD_TER RR2 6 "$42"
|
|
|
|
|
..TER U1 100
|
|
|
|
|
CA 6
|
|
|
|
|
|
|
|
|
|
..ADD_TER U2 6 "$59"
|
|
|
|
|
..TER U7 39
|
|
|
|
|
U6 17
|
|
|
|
|
U1 122
|
|
|
|
|
|
|
|
|
|
..ADD_TER P2 1 "$9"
|
|
|
|
|
..TER T3 1
|
|
|
|
|
U1 14
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
wxString StartCmpDesc = StartLine + wxT("ADD_COM");
|
|
|
|
|
wxString msg;
|
|
|
|
|
wxString FootprintName;
|
|
|
|
|
char Line[1024];
|
|
|
|
|
BASE_SCREEN *CurrScreen;
|
|
|
|
|
EDA_BaseStruct *DrawList;
|
|
|
|
|
EDA_SchComponentStruct *Component;
|
|
|
|
|
wxString Title = g_Main_Title + wxT(" ") + GetBuildVersion();
|
|
|
|
|
|
|
|
|
|
fprintf( f, "%sHEA\n", CONV_TO_UTF8(StartLine));
|
|
|
|
|
DateAndTime(Line);
|
|
|
|
|
fprintf( f, "%sTIM %s\n", CONV_TO_UTF8(StartLine), Line );
|
|
|
|
|
fprintf( f, "%sAPP ", CONV_TO_UTF8(StartLine) );
|
|
|
|
|
fprintf( f, "\"%s\"\n", CONV_TO_UTF8(Title) );
|
|
|
|
|
fprintf( f, "\n");
|
|
|
|
|
|
|
|
|
|
/* Create netlist module section */
|
|
|
|
|
ClearUsedFlags(frame); /* Reset the flags FlagControlMulti in all schematic files*/
|
2007-05-06 16:03:28 +00:00
|
|
|
|
EDA_ScreenList ScreenList(NULL);
|
|
|
|
|
for ( CurrScreen = ScreenList.GetFirst(); CurrScreen != NULL; CurrScreen = ScreenList.GetNext() )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
{
|
|
|
|
|
for ( DrawList = CurrScreen->EEDrawList; DrawList != NULL; DrawList = DrawList->Pnext )
|
|
|
|
|
{
|
|
|
|
|
DrawList = Component = FindNextComponentAndCreatPinList(DrawList);
|
|
|
|
|
if ( Component == NULL ) break;
|
|
|
|
|
|
|
|
|
|
if( ! Component->m_Field[FOOTPRINT].IsVoid() )
|
|
|
|
|
{
|
|
|
|
|
FootprintName = Component->m_Field[FOOTPRINT].m_Text;
|
|
|
|
|
FootprintName.Replace(wxT(" "), wxT("_"));
|
|
|
|
|
}
|
|
|
|
|
else FootprintName = wxT("$noname");
|
|
|
|
|
|
|
|
|
|
msg = Component->m_Field[REFERENCE].m_Text;
|
|
|
|
|
msg.Replace( wxT(" "), wxT("_"));
|
|
|
|
|
fprintf(f, "%s ", CONV_TO_UTF8(StartCmpDesc));
|
|
|
|
|
fprintf(f, "%s", CONV_TO_UTF8(msg));
|
|
|
|
|
|
|
|
|
|
msg = Component->m_Field[VALUE].m_Text;
|
|
|
|
|
msg.Replace(wxT(" "), wxT("_"));
|
|
|
|
|
fprintf(f, " \"%s\"", CONV_TO_UTF8(msg));
|
|
|
|
|
fprintf(f, "\n");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fprintf( f, "\n");
|
|
|
|
|
|
|
|
|
|
MyFree(s_SortedComponentPinList);
|
|
|
|
|
s_SortedComponentPinList = NULL;
|
|
|
|
|
|
|
|
|
|
WriteListOfNetsCADSTAR( f, g_TabObjNet );
|
|
|
|
|
|
|
|
|
|
fprintf( f, "\n%sEND\n", CONV_TO_UTF8(StartLine) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
|
static void WriteListOfNetsCADSTAR( FILE * f, ObjetNetListStruct *ObjNet )
|
|
|
|
|
/*************************************************************************/
|
|
|
|
|
/* Ecrit dans le fichier f la liste des nets ( classee par NetCodes ), et des
|
|
|
|
|
pins qui y sont connectes
|
|
|
|
|
format:
|
|
|
|
|
.ADD_TER RR2 6 "$42"
|
|
|
|
|
.TER U1 100
|
|
|
|
|
CA 6
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
wxString InitNetDesc = StartLine + wxT("ADD_TER");
|
|
|
|
|
wxString StartNetDesc = StartLine + wxT("TER");
|
|
|
|
|
wxString NetcodeName, InitNetDescLine;
|
|
|
|
|
int ii, jj, print_ter = 0;
|
|
|
|
|
int NetCode, LastNetCode = -1;
|
|
|
|
|
EDA_SchComponentStruct * Cmp;
|
|
|
|
|
wxString NetName;
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < g_NbrObjNet; ii++) ObjNet[ii].m_Flag = 0;
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < g_NbrObjNet; ii++)
|
|
|
|
|
{
|
|
|
|
|
// Get the NetName of the current net :
|
|
|
|
|
if( (NetCode = ObjNet[ii].m_NetCode) != LastNetCode )
|
|
|
|
|
{
|
|
|
|
|
NetName.Empty();
|
|
|
|
|
for (jj = 0; jj < g_NbrObjNet; jj++)
|
|
|
|
|
{
|
|
|
|
|
if( ObjNet[jj].m_NetCode != NetCode) continue;
|
|
|
|
|
if( ( ObjNet[jj].m_Type != NET_GLOBLABEL) &&
|
|
|
|
|
( ObjNet[jj].m_Type != NET_LABEL) &&
|
|
|
|
|
( ObjNet[jj].m_Type != NET_PINLABEL) ) continue;
|
|
|
|
|
|
|
|
|
|
NetName = * ObjNet[jj].m_Label; break;
|
|
|
|
|
}
|
|
|
|
|
NetcodeName = wxT("\"");
|
|
|
|
|
if( ! NetName.IsEmpty() )
|
|
|
|
|
{
|
|
|
|
|
NetcodeName += NetName;
|
|
|
|
|
if( g_TabObjNet[jj].m_Type != NET_PINLABEL)
|
|
|
|
|
NetcodeName << wxT("_") << g_TabObjNet[jj].m_SheetNumber;
|
|
|
|
|
}
|
|
|
|
|
else // this net has no name: create a default name $<net number>
|
|
|
|
|
NetcodeName << wxT("$") << NetCode;
|
|
|
|
|
NetcodeName += wxT("\"");
|
|
|
|
|
LastNetCode = NetCode;
|
|
|
|
|
print_ter = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( ObjNet[ii].m_Type != NET_PIN ) continue;
|
|
|
|
|
|
|
|
|
|
if ( ObjNet[ii].m_Flag != 0 ) continue;
|
|
|
|
|
|
|
|
|
|
Cmp = (EDA_SchComponentStruct*) ObjNet[ii].m_Link;
|
|
|
|
|
|
|
|
|
|
if ( Cmp->m_Field[REFERENCE].m_Text[0] == '#' )
|
|
|
|
|
continue; // Pseudo composant (symboles d'alims)
|
|
|
|
|
|
|
|
|
|
switch ( print_ter )
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
{
|
|
|
|
|
char buf[5];
|
|
|
|
|
wxString str_pinnum;
|
|
|
|
|
strncpy(buf, (char*) & ObjNet[ii].m_PinNum,4); buf[4] = 0;
|
|
|
|
|
str_pinnum = CONV_FROM_UTF8(buf);
|
|
|
|
|
InitNetDescLine.Printf( wxT("\n%s %s %.4s %s"),
|
|
|
|
|
InitNetDesc.GetData(),
|
|
|
|
|
Cmp->m_Field[REFERENCE].m_Text.GetData(),
|
|
|
|
|
str_pinnum.GetData(), NetcodeName.GetData());
|
|
|
|
|
}
|
|
|
|
|
print_ter++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
fprintf( f, "%s\n", CONV_TO_UTF8(InitNetDescLine));
|
|
|
|
|
fprintf( f, "%s %s %.4s\n",
|
|
|
|
|
CONV_TO_UTF8(StartNetDesc),
|
|
|
|
|
CONV_TO_UTF8(Cmp->m_Field[REFERENCE].m_Text),
|
|
|
|
|
(char*) & ObjNet[ii].m_PinNum );
|
|
|
|
|
print_ter++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
fprintf( f, " %s %.4s\n",
|
|
|
|
|
CONV_TO_UTF8(Cmp->m_Field[REFERENCE].m_Text),
|
|
|
|
|
(char*) & ObjNet[ii].m_PinNum );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ObjNet[ii].m_Flag = 1;
|
|
|
|
|
// Recherche des pins redondantes et mise a 1 de m_Flag,
|
|
|
|
|
// pour ne pas generer plusieurs fois la connexion
|
|
|
|
|
for (jj = ii + 1; jj < g_NbrObjNet; jj++)
|
|
|
|
|
{
|
|
|
|
|
if( ObjNet[jj].m_NetCode != NetCode) break;
|
|
|
|
|
if( ObjNet[jj].m_Type != NET_PIN ) continue;
|
|
|
|
|
EDA_SchComponentStruct * tstcmp =
|
|
|
|
|
(EDA_SchComponentStruct *) ObjNet[jj].m_Link;
|
|
|
|
|
if( Cmp->m_Field[REFERENCE].m_Text != tstcmp->m_Field[REFERENCE].m_Text ) continue;
|
|
|
|
|
|
|
|
|
|
if ( ObjNet[jj].m_PinNum == ObjNet[ii].m_PinNum ) ObjNet[jj].m_Flag = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|