/*------------------------------------------------------------------------ H M C O N T R O L _ A N S T O A module creating a slightly modified HMControl object suitable for the ANSTO HM. This works exactly the same as the existing HMControl, but has extra options (e.g. pausing HM's at the end of a count instead of stopping them). copyright: see copyright.h Mark Lesha, October 2006 -------------------------------------------------------------------------*/ #include #include #include #include "fortify.h" #include "hmcontrol.h" #include "hmcontrol_ansto.h" // extends hmcontrol.h #include "HistMem.h" #include "devexec.h" /*----------------------------------------------------------------------*/ extern int ANSTO_HTTP_PAUSE; static int HMCStatus_ANSTO(void *pData, SConnection *pCon) // A slightly modified version of the original HMCStatus(), // to support pause-on-count-terminate option for ANSTO HM, // and termination either by counter or by HM. { int status,i; pHMcontrol self = NULL; self = (pHMcontrol)pData; assert(self); // Termination happens when the selected device (counter or HM) terminates. status = self->slaves[((pHMcontrol_ANSTO)pData)->Termination_Object] ->CheckCountStatus(self->slaveData[((pHMcontrol_ANSTO)pData)->Termination_Object],pCon); if(status == HWIdle || status == HWFault) { /* stop counting on slaves when finished or when an error occurred. */ InvokeCallBack(self->pCall,COUNTEND,pCon); // If required, pause all objects when hm/count terminates // instead of stopping them. Use the existing interface // functions to do this. // ffr: NOTE: Pause() is now mapped to AnstoHttpVeto() // we need to call AnstoHttpPause() via the histmem Pause if (((pHMcontrol_ANSTO)pData)->Pause_HM_After_Count==1) { ANSTO_HTTP_PAUSE = 1; self->pCount->Pause(self,pCon); } else self->pCount->Halt(self); } /* Warning: this assumes that slaves 1 - MAXSLAVE are histogram memories. If this assumption does not hold, change this code to check if this is really a histogram memory. */ for(i = 1; i < MAXSLAVE; i++) { if(self->slaves[i] != NULL) { HistDirty((pHistMem)self->slaveData[i]); } } return status; } /*----------------------------------------------------------------------*/ int HMControlAction_ANSTO(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) // This function extends HMControlAction by looking for an optional fifth // and sixth command argument, which are stored to the expanded command data. // Thereafter the rest of the arguments are simply passed to the standard // HMControlAction function. { ((pHMcontrol_ANSTO)pData)->Pause_HM_After_Count=0; ((pHMcontrol_ANSTO)pData)->Termination_Object=0; if (argc>=5) { if (strcmp(argv[4],"pause")==0) ((pHMcontrol_ANSTO)pData)->Pause_HM_After_Count=1; else if (strcmp(argv[4],"stop")!=0) // default { SCWrite(pCon,"ERROR: Optional argument 5 must be 'stop' or 'pause'",eError); return 0; } } if (argc>=6) { if (sscanf(argv[5],"%d",&(((pHMcontrol_ANSTO)pData)->Termination_Object))!=1 || ((pHMcontrol_ANSTO)pData)->Termination_Object>=((pHMcontrol_ANSTO)pData)->hmc.nSlaves) { char errstr[256]; sprintf(errstr,"ERROR: Optional argument 6 must be integer 0 to %d, specifies termination object.", ((pHMcontrol_ANSTO)pData)->hmc.nSlaves - 1); SCWrite(pCon,errstr,eError); return 0; } } if (argc>=7) // too many args { SCWrite(pCon,"ERROR: Usage %s start preset mode",eError); return 0; } return HMControlAction(pCon, pSics, pData, argc, argv); } /*----------------------------------------------------------------------*/ int MakeHMControl_ANSTO(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { /* Start by making a plain vanilla HMControl object, */ /* which gets installed in the command list. */ if (!MakeHMControl(pCon, pSics, pData, argc, argv)) return 0; /* Find the new object in the command list. */ CommandList *pCommand; if (!(pCommand=FindCommand(pSics,argv[1]))) return 0; /* Get the original command's data, and add the extended command's data */ /* to it. The altered size of the object does not make any side effects. */ HMcontrol_ANSTO *newpData; if (!(newpData=(HMcontrol_ANSTO *)malloc(sizeof(HMcontrol_ANSTO)))) return 0; memcpy(newpData,pCommand->pData,sizeof(HMcontrol)); memset(((char *)newpData)+sizeof(HMcontrol),0,sizeof(HMcontrol_ANSTO)-sizeof(HMcontrol)); free(pCommand->pData); pCommand->pData=(void *)newpData; /* Customize the command handler and status reporting routine. */ pCommand->OFunc = HMControlAction_ANSTO; newpData->hmc.pCount->CheckCountStatus = HMCStatus_ANSTO; /* All done, return success. */ return 1; }