Files
sics/tasinit.c
cvs e64773949d - Fixed a couple of compiler found bugs generated by the new C compiler
- Added support to tasinit for status display part of tas-application
2001-01-15 10:05:43 +00:00

307 lines
9.4 KiB
C

/*--------------------------------------------------------------------------
This is one implementation file for the TASMAD simulation module for
SICS. The requirement is to make SICS look as much as TASMAD as
possible. This includes:
- TASMAD is variable driven
- Sometimes variables are accessed in storage order.
- A complicated calculation has to be done for getting the instruments
settings right. The appropriate F77 routine from TASMAD will be
reused.
- The scan logic is different.
- Output of ILL-formatted data files is required.
This file implements the initialization part of the whole thing.
Mark Koennecke, November 2000
---------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include "fortify.h"
#include "sics.h"
#include "sicsvar.h"
#include "counter.h"
#include "motor.h"
#include "scan.h"
#include "scan.i"
#include "tas.h"
/*
As variables may be accessed in storage order, it is necessary to
know the order of the motors
*/
extern char *tasMotorOrder[] = { "a1",
"a2",
"a3",
"a4",
"a5",
"a6",
"mcv",
"sro",
"ach",
"mtl",
"mtu",
"stl",
"stu",
"stl",
"atu",
"mgl",
"sgl",
"sgu",
"agl",
NULL };
/*
In order to initialise the variable array in the TAS data structure we
need to know the names of the variables in the right order. This order
has to match the order defined in tas.h through the defines. Otherwise
quite weird things may happen at runtime.
*/
extern char *tasVariableOrder[] = {
"wav",
"dm",
"da",
"etam",
"etaa",
"ti",
"mn",
"if1v",
"if1h",
"if2v",
"if2h",
"helm",
"as",
"bs",
"cs",
"aa",
"bb",
"cc",
"etas",
"ax",
"ay",
"az",
"bx",
"by",
"bz",
"ei",
"ki",
"ef",
"kf",
"qh",
"qk",
"ql",
"en",
"qm",
"hx",
"hy",
"hz",
"da1",
"da2",
"da3",
"da4",
"da5",
"da6",
"dmcv",
"dsro",
"dach",
"dmtl",
"dmtu",
"dstl",
"dstu",
"datl",
"datu",
"dmgl",
"dsgl",
"dsgu",
"dagl",
"dei",
"dki",
"def",
"dkf",
"dqh",
"dqk",
"dql",
"den",
"dqm",
"dt",
"sm",
"ss",
"sa",
"fx",
"np",
"f1",
"f2",
"lpa",
"mrx1",
"mrx2",
"arx1",
"arx2",
"instrument",
"title",
"user",
"lastcommand",
"alf1",
"alf2",
"alf3",
"alf4",
"bet1",
"bet2",
"bet3",
"bet4",
"output",
"local",
"swunit",
"scaninfo",
NULL};
/*---------------------------------------------------------------------
There is a special feauture in MAD where the count mode is determined
which variable, MN for monitor od TI for time has been set as the last
one. In order to implement this in SICS callback functions will be
used on the variables which switch the counter box into the appropriate
mode.
-----------------------------------------------------------------------*/
static int MonitorCallback(int iEvent, void *pEvent, void *pUser)
{
pTASdata self = (pTASdata)pUser;
assert(self);
if(iEvent != VALUECHANGE)
return 0;
SetCounterMode(self->pScan->pCounterData,ePreset);
SetCounterPreset(self->pScan->pCounterData,self->tasPar[MN]->fVal);
return 1;
}
static int TimerCallback(int iEvent, void *pEvent, void *pUser)
{
pTASdata self = (pTASdata)pUser;
assert(self);
if(iEvent != VALUECHANGE)
return 0;
SetCounterMode(self->pScan->pCounterData,eTimer);
SetCounterPreset(self->pScan->pCounterData,self->tasPar[TI]->fVal);
return 1;
}
/*-----------------------------------------------------------------------
A function for killing the TAS data structure is needed
-------------------------------------------------------------------------*/
static void TASKill(void *pData)
{
pTASdata self = (pTASdata)pData;
if(!self)
return;
if(self->pDes)
DeleteDescriptor(self->pDes);
free(self);
}
/*-----------------------------------------------------------------------*/
int TASFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
pTASdata pNew = NULL;
int iPtr, iError;
char pBueffel[132];
pSicsVariable pVar = NULL;
CommandList *pCom = NULL;
/* check arguments*/
if(argc < 2)
{
SCWrite(pCon,"ERROR: insufficient paarameters to MakeTAS",eError);
return 0;
}
/* create a new data structure */
pNew = (pTASdata)malloc(sizeof(TASdata));
if(!pNew)
{
SCWrite(pCon,"ERROR: insufficient memory to allocate TAS data structure",
eError);
return 0;
}
memset(pNew,0,sizeof(TASdata));
pNew->pDes = CreateDescriptor("TAS");
if(!pNew->pDes)
{
SCWrite(pCon,"ERROR: insufficient memory to allocate TAS data structure",
eError);
free(pNew);
return 0;
}
pNew->iPOL = -1;
/* connect to all the variables */
iPtr = 0; iError = 0;
while(tasVariableOrder[iPtr] != NULL)
{
pNew->tasPar[iPtr] = FindVariable(pSics,tasVariableOrder[iPtr]);
if(!pNew->tasPar[iPtr])
{
sprintf(pBueffel,"ERROR: TAS variable %s not found",
tasVariableOrder[iPtr]);
SCWrite(pCon,pBueffel,eError);
iError++;
}
iPtr++;
}
if(iError != 0)
{
SCWrite(pCon,"ERROR: TAS bad initialisation, TAS not created",eError);
TASKill(pNew);
return 0;
}
/* connect to the scan object */
pCom = FindCommand(pSics,argv[1]);
if(!pCom)
{
SCWrite(pCon,"ERROR: no scan routine for TAS found",eError);
TASKill(pNew);
return 0;
}
pNew->pScan = (pScanData)pCom->pData;
/*
Install the callbacks for TI and MN. Sloppy error checking because
the variables should have been accessed earlier on.
*/
pVar = FindVariable(pSics,"MN");
if(pVar)
{
RegisterCallback(pVar->pCall,VALUECHANGE,MonitorCallback,pNew,NULL);
}
pVar = FindVariable(pSics,"TI");
if(pVar)
{
RegisterCallback(pVar->pCall,VALUECHANGE,TimerCallback,pNew,NULL);
}
/* install TAS commands */
iError = AddCommand(pSics,"dr",TASDrive,TASKill,pNew);
if(!iError)
{
SCWrite(pCon,"ERROR: duplicate dr command not created",eError);
TASKill(pNew);
return 0;
}
iError = AddCommand(pSics,"sc",TASScan,NULL,pNew);
if(!iError)
{
SCWrite(pCon,"ERROR: duplicate sc command not created",eError);
TASKill(pNew);
return 0;
}
iError = AddCommand(pSics,"sf",TASScan,NULL,pNew);
if(!iError)
{
SCWrite(pCon,"ERROR: duplicate set command not created",eError);
TASKill(pNew);
return 0;
}
return 1;
}