/*------------------------------------------------------------------------- This is the implementation file for a driver for the Risoe A1931a temperature controller. This driver controls the device through a GPIB interface. copyright: see file COPYRIGHT Mark Koennecke, February 2003 -------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "A1931.h" /*========================== private data structure ====================*/ typedef struct { int sensor; /* the control sensor */ pGPIB gpib; /* the GPIB interface to use in order to talk to the thing*/ int gpibAddress; /* address on bus */ int devID; /* deviceID of the controller on the GPIB */ char errorBuffer[132]; /* a buffer for error messages from the thing*/ char commandLine[132]; /* buffer to keep the offending command line */ int errorCode; /* error indicator */ }A1931, *pA1931; /*============================ defines ================================*/ #define COMMERROR -300 #define A1931ERROR -301 #define FILEERROR -302 /*====================================================================*/ static char *A1931comm(pEVDriver pData, char *command){ char buffer[256], *pPtr; int status; pA1931 self = NULL; Tcl_DString reply; self = (pA1931)pData->pPrivate; assert(self); /* send */ strncpy(buffer,command,250); strcat(buffer,"\n"); status = GPIBsend(self->gpib,self->devID,buffer,(int)strlen(buffer)); if(status < 0){ self->errorCode = COMMERROR; GPIBerrorDescription(self->gpib,status,self->errorBuffer,131); return NULL; } /* read until > is found */ Tcl_DStringInit(&reply); while(1){ pPtr = GPIBreadTillTerm(self->gpib,self->devID,10); if(strstr(pPtr,"GPIB READ ERROR") != NULL){ free(pPtr); self->errorCode = COMMERROR; Tcl_DStringFree(&reply); return NULL; } else { Tcl_DStringAppend(&reply,pPtr,-1); if(strchr(pPtr,'>') != NULL){ /* finished */ free(pPtr); break; } free(pPtr); } } pPtr = NULL; pPtr = strdup(Tcl_DStringValue(&reply)); Tcl_DStringFree(&reply); if(pPtr[0] == '#'){ /* error */ self->errorCode = A1931ERROR; strncpy(self->errorBuffer,pPtr,131); free(pPtr); return NULL; } return pPtr; } /*--------------------------------------------------------------------*/ static int A1931command(pEVDriver pData, char *command, char *replyBuffer, int replyBufferLen){ pA1931 self = NULL; char *pReply = NULL; self = (pA1931)pData->pPrivate; assert(self); pReply = A1931comm(pData,command); if(pReply != NULL){ strncpy(replyBuffer,pReply,replyBufferLen); free(pReply); return 1; } else { strncpy(replyBuffer,self->errorBuffer,replyBufferLen); return 0; } } /*====================================================================*/ static int A1931Init(pEVDriver pData){ pA1931 self = NULL; self = (pA1931)pData->pPrivate; assert(self); self->devID = GPIBattach(self->gpib,0,self->gpibAddress,0,13,0,0); if(self->devID < 0){ return 0; } return 1; } /*====================================================================*/ static int A1931Close(pEVDriver pData){ pA1931 self = NULL; self = (pA1931)pData->pPrivate; assert(self); GPIBdetach(self->gpib,self->devID); self->devID = 0; return 1; } /*===================================================================*/ static int A1931Get(pEVDriver pData,float *fPos){ pA1931 self = NULL; char buffer[132], command[50]; int status; self = (pA1931)pData->pPrivate; assert(self); sprintf(command,"?TEMP%1.1d",self->sensor); status = A1931command(pData,command,buffer,131); if(!status){ return 0; } sscanf(buffer,"%f",fPos); return 1; } /*=====================================================================*/ static int A1931Set(pEVDriver pData, float fNew){ pA1931 self = NULL; char buffer[132], command[50]; int status; self = (pA1931)pData->pPrivate; assert(self); sprintf(command,"SET%1.1d=%f",self->sensor,fNew); status = A1931command(pData,command,buffer,131); if(!status){ return 0; } return 1; } /*====================================================================*/ static int A1931error(pEVDriver pData, int *iCode, char *errBuff, int bufLen){ pA1931 self = NULL; char pError[256]; self = (pA1931)pData->pPrivate; assert(self); *iCode = self->errorCode; sprintf(pError,"ERROR: %s",self->errorBuffer); strncpy(errBuff,pError,bufLen); return 1; } /*====================================================================*/ static int A1931fix(pEVDriver pData, int iCode){ pA1931 self = NULL; char pError[256]; self = (pA1931)pData->pPrivate; assert(self); if(iCode == COMMERROR){ GPIBclear(self->gpib,self->devID); return DEVREDO; } return DEVFAULT; } /*=====================================================================*/ pEVDriver CreateA1931Driver(int argc, char *argv[]){ pEVDriver self = NULL; pA1931 priv = NULL; if(argc < 2){ return NULL; } /* allocate space */ self = CreateEVDriver(argc,argv); priv = (pA1931)malloc(sizeof(A1931)); if(self == NULL || priv == NULL){ return NULL; } memset(priv,0,sizeof(A1931)); self->pPrivate = priv; self->KillPrivate = free; /* initialize */ priv->gpib = (pGPIB)FindCommandData(pServ->pSics,argv[0],"GPIB"); if(!priv->gpib){ DeleteEVDriver(self); return NULL; } priv->sensor = 1; priv->gpibAddress = atoi(argv[1]); /* initialize function pointers */ self->Send = A1931command; self->Init = A1931Init; self->Close = A1931Close; self->GetValue = A1931Get; self->SetValue = A1931Set; self->GetError = A1931error; self->TryFixIt = A1931fix; return self; } /*=======================================================================*/ static int downloadFile(pA1931 self, FILE *fd){ char buffer[132], *pPtr; int status; while(1){ if(fgets(buffer,130,fd) == NULL){ self->errorCode = FILEERROR; strcpy(self->errorBuffer,"Failed to read from file"); return 0; } if(strstr(buffer,"$END") != NULL){ break; } status = GPIBsend(self->gpib,self->devID,buffer,(int)strlen(buffer)); if(status < 0){ self->errorCode = COMMERROR; GPIBerrorDescription(self->gpib,status,self->errorBuffer,131); return 0; } pPtr = GPIBreadTillTerm(self->gpib,self->devID,10); if(pPtr[0] == '#'){ self->errorCode = A1931ERROR; strncpy(self->errorBuffer,pPtr,131); strncpy(self->commandLine,buffer,131); free(pPtr); return 0; } free(pPtr); usleep(50); } return 1; } /*=======================================================================*/ int A1931Action(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){ pEVControl pEV = NULL; pA1931 self = NULL; char buffer[256]; char error[132]; FILE *fd = NULL; int status, iCode; pEV = (pEVControl)pData; assert(pEV); self = (pA1931)pEV->pDriv->pPrivate; assert(self); if(argc > 1){ strtolower(argv[1]); if(strcmp(argv[1],"sensor") == 0){ if(argc > 2){ /* set case */ if(!SCMatchRights(pCon,usUser)){ return 0; } self->sensor = atoi(argv[2]); SCSendOK(pCon); return 1; } else { /* get case */ sprintf(buffer,"%s.sensor = %d",argv[0],self->sensor); SCWrite(pCon,buffer,eValue); return 1; } }else if(strcmp(argv[1],"list") == 0){ sprintf(buffer,"%s.sensor = %d",argv[0],self->sensor); SCWrite(pCon,buffer,eValue); return EVControlWrapper(pCon,pSics,pData,argc,argv); } else if(strcmp(argv[1],"file") == 0){ if(!SCMatchRights(pCon,usUser)){ return 0; } if(argc < 3){ SCWrite(pCon,"ERROR: need filename argument",eError); return 0; } fd = fopen(argv[2],"r"); if(fd == NULL){ sprintf(buffer,"ERROR: failed to open %s", argv[2]); SCWrite(pCon,buffer,eError); return 0; } status = downloadFile(self,fd); fclose(fd); if(!status){ A1931error(pEV->pDriv,&iCode,error,131); sprintf(buffer,"%s while transfering file", error); SCWrite(pCon,buffer,eError); sprintf(buffer,"Offending command: %s",self->commandLine); SCWrite(pCon,buffer,eError); return 0; } SCSendOK(pCon); return 1; } } return EVControlWrapper(pCon,pSics,pData,argc,argv); }