/*------------------------------------------------------------------------- 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 */ strlcpy(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; strlcpy(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) { strlcpy(replyBuffer, pReply, replyBufferLen); free(pReply); return 1; } else { strlcpy(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); strlcpy(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; strlcpy(self->errorBuffer, pPtr, 131); strlcpy(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); }