From e929275cdfa7d702a29921b1945a669c19ef7cc4 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Sun, 14 Jul 2013 18:54:44 +0200 Subject: [PATCH] sharedspice.c, .h: fcn to initialize Sync, fcn to set breakpoint, callback fcn to read vsrc external inputs --- src/include/ngspice/sharedspice.h | 22 +++++++ src/sharedspice.c | 106 ++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/src/include/ngspice/sharedspice.h b/src/include/ngspice/sharedspice.h index 3235f9460..a9ff1858e 100644 --- a/src/include/ngspice/sharedspice.h +++ b/src/include/ngspice/sharedspice.h @@ -209,6 +209,18 @@ typedef int (BGThreadRunning)(bool, void*); void* return pointer received from caller */ +/* callback functions + addresses received from caller with ngSpice_Init_Sync() function +*/ + +/* ask for VSRC EXTERNAL value */ +typedef int (GetVSRCData)(double*, double, char*, void*); +/* + double* return voltage value + double actual time + char* node name + void* return pointer received from caller +*/ /* ngspice initialization, printfcn: pointer to callback function for reading printf, fprintf @@ -223,6 +235,12 @@ IMPEXP int ngSpice_Init(SendChar* printfcn, SendStat* statfcn, ControlledExit* ngexit, SendData* sdata, SendInitData* sinitdata, BGThreadRunning* bgtrun, void* userData); +/* initialization of synchronizing functions +vsrcdat: pointer to callback function for retrieving a voltage source value +ident: pointer to integer unique to this shared library (defaults to 0) +*/ +IMPEXP +int ngSpice_Init_Sync(GetVSRCData *vsrcdat, int *ident, void *userData); /* Caller may send ngspice commands to ngspice.dll. Commands are executed immediately */ @@ -263,6 +281,10 @@ char** ngSpice_AllVecs(char* plotname); IMPEXP bool ngSpice_running(void); +/* set a breakpoint in ngspice */ +IMPEXP +bool ngSpice_SetBkpt(double time); + #ifdef __cplusplus } diff --git a/src/sharedspice.c b/src/sharedspice.c index 0a08ad783..e4db4a107 100644 --- a/src/sharedspice.c +++ b/src/sharedspice.c @@ -192,6 +192,7 @@ int sh_vfprintf(FILE *f, const char *fmt, va_list args); int sh_fputsll(const char *input, FILE* outf); int sh_ExecutePerLoop(void); +double getvsrcval(double, char*); int sh_vecinit(runDesc *run); void shared_exit(int status); @@ -200,6 +201,8 @@ void sighandler_sharedspice(int num); void wl_delete_first(wordlist **wlstart, wordlist **wlend); +int add_bkpt(void); + #if !defined(low_latency) static char* outstorage(char*, bool); static void printsend(void); @@ -214,6 +217,7 @@ static ControlledExit* ngexit; static SendData* datfcn; static SendInitData* datinitfcn; static BGThreadRunning* bgtr; +static GetVSRCData* getvdat; static pvector_info myvec = NULL; char **allvecs = NULL; char **allplots = NULL; @@ -222,6 +226,7 @@ static bool nostatuswanted = FALSE; static bool nodatawanted = FALSE; static bool nodatainitwanted = FALSE; static bool nobgtrwanted = FALSE; +static bool wantvdat = FALSE; static bool immediate = FALSE; static bool coquit = FALSE; static jmp_buf errbufm, errbufc; @@ -241,6 +246,9 @@ mutexType fputsMutex; static bool is_initialized = FALSE; static char* no_init = "Error: ngspice is not initialized!\n Run ngSpice_Init first"; +/* identifier for this ngspice invocation */ +static int ng_ident = 0; + static struct plot * get_plot_byname(char* plotname) @@ -477,6 +485,26 @@ ngSpice_running (void) #endif +/* Initialise external voltage source */ +IMPEXP +int +ngSpice_Init_Sync(GetVSRCData* vsrcdat, int *ident, void *userData) +{ + getvdat = vsrcdat; + /* set userdata, but don't overwrite with NULL */ + if (userData) + userptr = userData; + /* set ngspice shared lib identification number */ + ng_ident = *ident; + /* if caller sends NULL, don't try to retrieve voltage */ + if (getvdat) { + wantvdat = TRUE; + return 0; + } + return 1; +} + + /* Initialise ngspice and setup native methods */ IMPEXP int @@ -803,6 +831,67 @@ char** ngSpice_AllVecs(char* plotname) } +static double *bkpttmp = NULL; +static int bkpttmpsize = 0; + +/* set a breakpoint in ngspice */ +IMPEXP +bool ngSpice_SetBkpt(double time) +{ + int error; + CKTcircuit *ckt = NULL; + + if (!ft_curckt || !ft_curckt->ci_ckt) { + fprintf(cp_err, "Error: no circuit loaded.\n"); + return(FALSE); + } + + ckt = ft_curckt->ci_ckt; + if (ckt->CKTbreakSize == 0) { + /* breakpoints have not yet been set up, so store here preliminary + and add with fcn add_bkpt() called from DCTran() */ + if (bkpttmp == NULL) { + bkpttmp = TMALLOC(double, bkpttmpsize + 1); + if(bkpttmp == NULL) + return(FALSE); + bkpttmpsize++; + } + else { + bkpttmp = TREALLOC(double, bkpttmp, bkpttmpsize + 1); + bkpttmpsize++; + } + bkpttmp[bkpttmpsize-1] = time; + error = 0; + } + else + error = CKTsetBreak(ckt, time); + if(error) + return(FALSE); + return(TRUE); +} + + +/* add the preliminary breakpoints to the list. + called from dctran.c */ +int +add_bkpt(void) +{ + int i; + int error = 0; + CKTcircuit *ckt = ft_curckt->ci_ckt; + + if((bkpttmp) && (bkpttmpsize > 0)) { + for (i = 0; i < bkpttmpsize; i++) + error = CKTsetBreak(ckt, bkpttmp[i]); + FREE(bkpttmp); + bkpttmpsize = 0; + } + if(error) + return(error); + return(OK); +} + + /*------------------------------------------------------*/ /* Redefine the vfprintf() functions for callback */ /*------------------------------------------------------*/ @@ -1591,3 +1680,20 @@ int sh_vecinit(runDesc *run) return 0; } + +/* issue callback to request external voltage data for source vname */ +double +getvsrcval(double time, char *vname) +{ + double vval; + if (!wantvdat) { + fprintf(stderr, "Error: No callback supplied for source %s\n", vname); + shared_exit(EXIT_BAD); + return(EXIT_BAD); + } + else { + /* callback fcn */ + getvdat(&vval, time, vname, userptr); + return vval; + } +}