Largely comments and splint conformance
r1070 | dcl | 2006-08-21 09:47:25 +1000 (Mon, 21 Aug 2006) | 2 lines
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include "fortify.h"
|
#include "fortify.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sics.h>
|
#include <sics.h>
|
||||||
@@ -20,17 +21,28 @@
|
|||||||
#include <countdriv.h>
|
#include <countdriv.h>
|
||||||
#include "anstoutil.h"
|
#include "anstoutil.h"
|
||||||
|
|
||||||
#define FAILURE 0
|
#ifdef SPLINT
|
||||||
#define SUCCESS 1
|
/*@-incondefs@*/
|
||||||
|
int gettimeofday(/*@out@*/ struct timeval *restrict tp,
|
||||||
|
/*@null@*/ void *restrict tzp);
|
||||||
|
char *strdup(const char *s);
|
||||||
|
int strcasecmp(const char *s1, const char *s2);
|
||||||
|
int strncasecmp(const char *s1, const char *s2, size_t n);
|
||||||
|
unsigned long long int
|
||||||
|
strtoull(const char *nptr, /*@null@*/ char **endptr, int base);
|
||||||
|
/*@+incondefs@*/
|
||||||
|
#endif
|
||||||
|
|
||||||
/*@-incondefs@*/
|
/*@-incondefs@*/
|
||||||
/*@observer@*//*@dependent@*/ Tcl_Interp *InterpGetTcl(SicsInterp *pSics);
|
/*@observer@*//*@dependent@*/ Tcl_Interp *InterpGetTcl(SicsInterp *pSics);
|
||||||
int readRS232(prs232 self, /*@out@*/void *data, /*@out@*/int *dataLen);
|
int readRS232(prs232 self, /*@out@*/void *data, /*@out@*/int *dataLen);
|
||||||
|
int readRS232TillTerm(prs232 self, /*@out@*/void *data, /*@out@*/int *dataLen);
|
||||||
void getRS232Error(int iCode, /*@out@*/ char *errorBuffer, int errorBufferLen);
|
void getRS232Error(int iCode, /*@out@*/ char *errorBuffer, int errorBufferLen);
|
||||||
/*@observer@*//*@dependent@*/ pCounterDriver CreateCounterDriver(char *name, char *type);
|
/*@observer@*//*@dependent@*/ pCounterDriver CreateCounterDriver(char *name, char *type);
|
||||||
void KillRS232(/*@only@ frees pData */ void *pData);
|
void KillRS232(/*@only@ frees pData */ void *pData);
|
||||||
/*@+incondefs@*/
|
/*@+incondefs@*/
|
||||||
|
|
||||||
|
typedef unsigned long long int uint64;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int length;
|
int length;
|
||||||
@@ -46,17 +58,22 @@ typedef struct {
|
|||||||
int iPort;
|
int iPort;
|
||||||
float dummy_threshold;
|
float dummy_threshold;
|
||||||
BUFFER buffer;
|
BUFFER buffer;
|
||||||
unsigned long long counter_value;
|
uint64 counter_value;
|
||||||
} BeamMon, *pBeamMon;
|
} BeamMon, *pBeamMon;
|
||||||
|
|
||||||
static int MonSend(CounterDriver *cntrData, char *pText, char *pReply, int iReplyLen);
|
/** \brief file logging
|
||||||
|
*
|
||||||
|
* Logs text to a debug file. The file is opened and closed for each call.
|
||||||
|
*
|
||||||
|
* \param flag character used to distinguish calls
|
||||||
|
* \param pText pointer to text to be logged
|
||||||
|
*/
|
||||||
static void flog(char flag, char* pText) {
|
static void flog(char flag, char* pText) {
|
||||||
FILE* file;
|
FILE* file;
|
||||||
file = fopen("flog.txt", "a");
|
file = fopen("flog.txt", "a");
|
||||||
if (file) {
|
if (file) {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday(&tv, NULL);
|
(void) gettimeofday(&tv, NULL);
|
||||||
fprintf(file, "%02d:%02d:%02d:%06d::%c::%s",
|
fprintf(file, "%02d:%02d:%02d:%06d::%c::%s",
|
||||||
tv.tv_sec % (24 * 3600) / 3600,
|
tv.tv_sec % (24 * 3600) / 3600,
|
||||||
tv.tv_sec % (3600) / 60,
|
tv.tv_sec % (3600) / 60,
|
||||||
@@ -65,8 +82,8 @@ static void flog(char flag, char* pText) {
|
|||||||
flag,
|
flag,
|
||||||
pText);
|
pText);
|
||||||
if (strchr(pText, '\n') == NULL)
|
if (strchr(pText, '\n') == NULL)
|
||||||
fputc('\n', file);
|
(void) fputc('\n', file);
|
||||||
fclose(file);
|
(void) fclose(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,19 +92,17 @@ static void flog(char flag, char* pText) {
|
|||||||
*
|
*
|
||||||
* \param *cntrData provides access to a monitor's data
|
* \param *cntrData provides access to a monitor's data
|
||||||
* \param *text pointer to NULL terminated text to send.
|
* \param *text pointer to NULL terminated text to send.
|
||||||
* \return
|
* \return SUCCESS or FAILURE
|
||||||
* - SUCCESS
|
|
||||||
* - FAILURE
|
|
||||||
*/
|
*/
|
||||||
static int MonWrite(pBeamMon self, char* text) {
|
static int MonWrite(pBeamMon self, char* text) {
|
||||||
int len;
|
size_t len;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
len = strlen(text);
|
len = strlen(text);
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
flog('>', text);
|
flog('>', text);
|
||||||
|
|
||||||
status = writeRS232(self->controller, text, len);
|
status = writeRS232(self->controller, text, (int) len);
|
||||||
if (status != 1) {
|
if (status != 1) {
|
||||||
self->errorCode = status;
|
self->errorCode = status;
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
@@ -101,13 +116,12 @@ static int MonWrite(pBeamMon self, char* text) {
|
|||||||
* \param *cntrData provides access to a monitor's data
|
* \param *cntrData provides access to a monitor's data
|
||||||
* \param *text pointer to NULL terminated text to receive.
|
* \param *text pointer to NULL terminated text to receive.
|
||||||
* \param *pLen inout pointer to length of text to receive.
|
* \param *pLen inout pointer to length of text to receive.
|
||||||
* \return
|
* \return SUCCESS or FAILURE
|
||||||
* - SUCCESS
|
|
||||||
* - FAILURE
|
|
||||||
*/
|
*/
|
||||||
static int MonRead(pBeamMon self, char* text, int *pLen) {
|
static int MonRead(pBeamMon self, /*@out@*/ char* text, int *pLen) {
|
||||||
int i, status, retries=20;
|
int i, status, retries=20;
|
||||||
|
|
||||||
|
*text = '\0';
|
||||||
for (i=0; i<retries; i++) {
|
for (i=0; i<retries; i++) {
|
||||||
status = readRS232TillTerm(self->controller, text, pLen);
|
status = readRS232TillTerm(self->controller, text, pLen);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
@@ -129,16 +143,86 @@ static int MonRead(pBeamMon self, char* text, int *pLen) {
|
|||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief drains any pending input on the RS232 channel
|
||||||
|
*
|
||||||
|
* \param *cntrData provides access to a monitor's data
|
||||||
|
*/
|
||||||
|
static void MonDrainInput(CounterDriver *cntrData) {
|
||||||
|
int iRet;
|
||||||
|
int len;
|
||||||
|
char reply[1024];
|
||||||
|
BeamMon* self = NULL;
|
||||||
|
self = (BeamMon *) cntrData->pData;
|
||||||
|
while (availableRS232(self->controller) != 0) {
|
||||||
|
len = (int) sizeof(reply);
|
||||||
|
iRet = MonRead(self, reply, &len);
|
||||||
|
if (iRet == FAILURE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief sends a command to the monitor and gets the reply
|
||||||
|
*
|
||||||
|
* \param cntrData provides access to a monitor's data
|
||||||
|
* \param pText command to send
|
||||||
|
* \param pReply space for reply
|
||||||
|
* \param iReplyLen length of space for reply
|
||||||
|
* \return SUCCESS or FAILURE
|
||||||
|
*/
|
||||||
|
static int MonSend(CounterDriver *cntrData, char *pText, char *pReply, int iReplyLen) {
|
||||||
|
BeamMon *self = NULL;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
self = (BeamMon *) cntrData->pData;
|
||||||
|
MonDrainInput(cntrData);
|
||||||
|
status = MonWrite(self, pText);
|
||||||
|
if (status != SUCCESS)
|
||||||
|
return status;
|
||||||
|
if ((status = MonRead(self, pReply, &iReplyLen)) == SUCCESS)
|
||||||
|
{
|
||||||
|
pReply[iReplyLen] = '\0';
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief sends a command to the monitor and gets the reply
|
||||||
|
*
|
||||||
|
* \param cntrData provides access to a monitor's data
|
||||||
|
* \param pText command to send
|
||||||
|
* \param buffer space for reply
|
||||||
|
* \return SUCCESS or FAILURE
|
||||||
|
*/
|
||||||
|
static int MonSendBuffer(CounterDriver *cntrData, char *pText, BUFFER* buffer) {
|
||||||
|
int status;
|
||||||
|
buffer->length = 0;
|
||||||
|
status = MonSend(cntrData, pText, buffer->body, (int) sizeof(buffer->body));
|
||||||
|
if (status == SUCCESS) {
|
||||||
|
buffer->length = (int) strlen(buffer->body);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/** \brief parses and acts upon the READ line
|
||||||
|
*
|
||||||
|
* \param *cntrData provides access to a monitor's data
|
||||||
|
* \param bp pointer to buffer containing the text line
|
||||||
|
*
|
||||||
|
* This function sets the state of the counter based on state flags reported by
|
||||||
|
* the monitor.
|
||||||
|
*/
|
||||||
static void HandleReport(CounterDriver *cntrData, BUFFER* bp)
|
static void HandleReport(CounterDriver *cntrData, BUFFER* bp)
|
||||||
{
|
{
|
||||||
//READ xxxx 00:00:00.000000 0.000000 0 0.00
|
//READ xxxx 00:00:00.000000 0.000000 0 0.00
|
||||||
//0123456789012345678901234567890
|
//0123456789012345678901234567890
|
||||||
BeamMon* self = NULL;
|
BeamMon* self = NULL;
|
||||||
|
char *cp = NULL;
|
||||||
|
char *ep = NULL;
|
||||||
|
char str[100];
|
||||||
self = (BeamMon *) cntrData->pData;
|
self = (BeamMon *) cntrData->pData;
|
||||||
/* TODO better than this */
|
/* TODO better than this */
|
||||||
char* cp = &bp->body[26];
|
cp = &bp->body[26];
|
||||||
char* ep;
|
cntrData->fTime = (float) strtod(cp, &ep);
|
||||||
cntrData->fTime = strtod(cp, &ep);
|
|
||||||
cp = ep;
|
cp = ep;
|
||||||
switch (toupper(bp->body[5])) {
|
switch (toupper(bp->body[5])) {
|
||||||
case 'I': /* idle */
|
case 'I': /* idle */
|
||||||
@@ -151,16 +235,16 @@ static void HandleReport(CounterDriver *cntrData, BUFFER* bp)
|
|||||||
case 'P': /* paused */
|
case 'P': /* paused */
|
||||||
self->state = HWPause;
|
self->state = HWPause;
|
||||||
break;
|
break;
|
||||||
default:
|
default: /* should not happen */
|
||||||
self->state = HWFault;
|
self->state = HWFault;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (toupper(bp->body[8] == 'G')) /* Gated */
|
if ((self->state == HWBusy || self->state == HWPause)
|
||||||
|
&& (toupper(bp->body[8]) == (int) 'G')) /* Gated */
|
||||||
self->state = HWNoBeam;
|
self->state = HWNoBeam;
|
||||||
self->counter_value = strtoull(cp, &ep, 10);
|
self->counter_value = strtoull(cp, &ep, 10);
|
||||||
cntrData->fLastCurrent = self->counter_value;
|
cntrData->fLastCurrent = (float) self->counter_value;
|
||||||
char str[100];
|
(void) snprintf(str, sizeof(str), "READ %s, %f, %f, %f\n",
|
||||||
snprintf(str, sizeof(str), "READ %s, %f, %f, %f\n",
|
|
||||||
cntrData->eMode == eTimer ? "eTimer" :
|
cntrData->eMode == eTimer ? "eTimer" :
|
||||||
cntrData->eMode == ePreset ? "ePreset" : "Unknown",
|
cntrData->eMode == ePreset ? "ePreset" : "Unknown",
|
||||||
cntrData->fPreset,
|
cntrData->fPreset,
|
||||||
@@ -169,70 +253,60 @@ static void HandleReport(CounterDriver *cntrData, BUFFER* bp)
|
|||||||
flog('.', str);
|
flog('.', str);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int MonDrainInput(CounterDriver *cntrData) {
|
/** \brief handles an input line received on the RS232 channel
|
||||||
int iRet, len;
|
*
|
||||||
char reply[1024];
|
* \param cntrData provides access to a monitor's data
|
||||||
|
* \param bp pointer to buffer containing the line of input
|
||||||
|
*
|
||||||
|
* This function sets the state of the counter based on events reported by
|
||||||
|
* the monitor.
|
||||||
|
*/
|
||||||
|
static void MonHandleInput(CounterDriver *cntrData, BUFFER* bp) {
|
||||||
BeamMon* self = NULL;
|
BeamMon* self = NULL;
|
||||||
self = (BeamMon *) cntrData->pData;
|
const char et[] = "EVENT TERMINAL";
|
||||||
while (availableRS232(self->controller)) {
|
const char eri[] = "EVENT RANGE IN";
|
||||||
len = sizeof(reply);
|
const char ero[] = "EVENT RANGE OUT";
|
||||||
iRet = MonRead(self, reply, &len);
|
const char rpt[] = "READ";
|
||||||
if (iRet == FAILURE) {
|
|
||||||
return iRet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int MonHandleInput(CounterDriver *cntrData, BUFFER* bp) {
|
|
||||||
BeamMon* self = NULL;
|
|
||||||
int iRet, len;
|
|
||||||
int iLen = 0;
|
|
||||||
int jLen = 0;
|
|
||||||
char reply[1024];
|
|
||||||
char* pTerm;
|
|
||||||
|
|
||||||
self = (BeamMon *) cntrData->pData;
|
self = (BeamMon *) cntrData->pData;
|
||||||
/* TODO handle the line */
|
/* TODO handle the line */
|
||||||
flog('<', bp->body);
|
flog('=', bp->body);
|
||||||
const char et[] = "EVENT TERMINAL";
|
|
||||||
if (strncasecmp(bp->body, et, sizeof(et) - 1) == 0) {
|
if (strncasecmp(bp->body, et, sizeof(et) - 1) == 0) {
|
||||||
if (self->state == HWBusy)
|
if (self->state == HWBusy)
|
||||||
self->state = HWIdle;
|
self->state = HWIdle;
|
||||||
}
|
}
|
||||||
const char eri[] = "EVENT RANGE IN";
|
|
||||||
if (strncasecmp(bp->body, eri, sizeof(eri) - 1) == 0)
|
if (strncasecmp(bp->body, eri, sizeof(eri) - 1) == 0)
|
||||||
if (self->state == HWPause)
|
if (self->state == HWPause)
|
||||||
self->state = HWBusy;
|
self->state = HWBusy;
|
||||||
const char ero[] = "EVENT RANGE OUT";
|
|
||||||
if (strncasecmp(bp->body, ero, sizeof(ero) - 1) == 0)
|
if (strncasecmp(bp->body, ero, sizeof(ero) - 1) == 0)
|
||||||
if (self->state == HWBusy)
|
if (self->state == HWBusy)
|
||||||
self->state = HWPause;
|
self->state = HWPause;
|
||||||
const char rpt[] = "READ";
|
|
||||||
if (strncasecmp(bp->body, rpt, sizeof(rpt) - 1) == 0) {
|
if (strncasecmp(bp->body, rpt, sizeof(rpt) - 1) == 0) {
|
||||||
if (self->state == HWBusy) {
|
|
||||||
HandleReport(cntrData, &self->buffer);
|
HandleReport(cntrData, &self->buffer);
|
||||||
MonWrite(self, "SICS READ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
bp->length = 0;
|
bp->length = 0;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int MonLookForInput(CounterDriver *cntrData, int timeout) {
|
/** \brief look for input on the socket
|
||||||
|
*
|
||||||
|
* breaks input into lines terminated by <CR><LF> pairs and passes complete lines to MonHandleInput for processing.
|
||||||
|
*
|
||||||
|
* \param cntrData provides access to a monitor's data
|
||||||
|
* \param timeout upper limit on time to wait for data to arrive
|
||||||
|
*/
|
||||||
|
static void MonLookForInput(CounterDriver *cntrData, /*@unused@*/ int timeout) {
|
||||||
BeamMon* self = NULL;
|
BeamMon* self = NULL;
|
||||||
int iRet, len;
|
int iRet, len;
|
||||||
int iLen = 0;
|
int iLen = 0;
|
||||||
int jLen = 0;
|
int jLen = 0;
|
||||||
char reply[1024];
|
char reply[1024];
|
||||||
char* pTerm;
|
|
||||||
|
|
||||||
self = (BeamMon *) cntrData->pData;
|
self = (BeamMon *) cntrData->pData;
|
||||||
while (availableRS232(self->controller)) {
|
while (availableRS232(self->controller) != 0) {
|
||||||
len = sizeof(reply);
|
len = (int) sizeof(reply);
|
||||||
iRet = MonRead(self, reply, &len);
|
iRet = MonRead(self, reply, &len);
|
||||||
if (iRet == FAILURE) {
|
if (iRet == FAILURE) {
|
||||||
return iRet;
|
return;
|
||||||
}
|
}
|
||||||
iLen = 0;
|
iLen = 0;
|
||||||
while (iLen < len) {
|
while (iLen < len) {
|
||||||
@@ -243,7 +317,7 @@ static int MonLookForInput(CounterDriver *cntrData, int timeout) {
|
|||||||
jLen = len - iLen;
|
jLen = len - iLen;
|
||||||
strncpy(&self->buffer.body[self->buffer.length],
|
strncpy(&self->buffer.body[self->buffer.length],
|
||||||
&reply[iLen],
|
&reply[iLen],
|
||||||
jLen);
|
(size_t) jLen);
|
||||||
self->buffer.length += jLen;
|
self->buffer.length += jLen;
|
||||||
self->buffer.body[self->buffer.length] = '\0';
|
self->buffer.body[self->buffer.length] = '\0';
|
||||||
iLen += jLen;
|
iLen += jLen;
|
||||||
@@ -254,7 +328,6 @@ static int MonLookForInput(CounterDriver *cntrData, int timeout) {
|
|||||||
self->buffer.length = 0;
|
self->buffer.length = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Returns the counter status,
|
/** \brief Returns the counter status,
|
||||||
@@ -275,7 +348,7 @@ static int MonGetStatus(CounterDriver *cntrData, float *fControl) {
|
|||||||
|
|
||||||
self = (BeamMon *) cntrData->pData;
|
self = (BeamMon *) cntrData->pData;
|
||||||
MonLookForInput(cntrData, 0);
|
MonLookForInput(cntrData, 0);
|
||||||
status = MonSend(cntrData, "SICS READ", self->buffer.body, sizeof(self->buffer.body));
|
status = MonSendBuffer(cntrData, "SICS READ", &self->buffer);
|
||||||
if (status == SUCCESS) {
|
if (status == SUCCESS) {
|
||||||
/* TODO */
|
/* TODO */
|
||||||
MonHandleInput(cntrData, &self->buffer);
|
MonHandleInput(cntrData, &self->buffer);
|
||||||
@@ -302,11 +375,18 @@ static int MonGetStatus(CounterDriver *cntrData, float *fControl) {
|
|||||||
/** \brief Starts counting in the current mode and with the current preset
|
/** \brief Starts counting in the current mode and with the current preset
|
||||||
*
|
*
|
||||||
* \param *cntrData provides access to a monitor's data
|
* \param *cntrData provides access to a monitor's data
|
||||||
|
* \return SUCCESS or FAILURE
|
||||||
|
*
|
||||||
|
* This function also sets some of the parameters in the monitor for mode and
|
||||||
|
* preset.
|
||||||
|
*
|
||||||
|
* TODO: check the return from the monitor
|
||||||
*/
|
*/
|
||||||
static int MonStart(CounterDriver *cntrData) {
|
static int MonStart(CounterDriver *cntrData) {
|
||||||
BeamMon *self = NULL;
|
BeamMon *self = NULL;
|
||||||
|
int status;
|
||||||
char str[100];
|
char str[100];
|
||||||
snprintf(str, sizeof(str), "START %s, %f, %f, %f\n",
|
(void) snprintf(str, sizeof(str), "START %s, %f, %f, %f\n",
|
||||||
cntrData->eMode == eTimer ? "eTimer" :
|
cntrData->eMode == eTimer ? "eTimer" :
|
||||||
cntrData->eMode == ePreset ? "ePreset" : "Unknown",
|
cntrData->eMode == ePreset ? "ePreset" : "Unknown",
|
||||||
cntrData->fPreset,
|
cntrData->fPreset,
|
||||||
@@ -316,18 +396,34 @@ static int MonStart(CounterDriver *cntrData) {
|
|||||||
self = (BeamMon *) cntrData->pData;
|
self = (BeamMon *) cntrData->pData;
|
||||||
MonDrainInput(cntrData);
|
MonDrainInput(cntrData);
|
||||||
if (cntrData->eMode == eTimer) {
|
if (cntrData->eMode == eTimer) {
|
||||||
MonSend(cntrData, "SICS SET TE_CHECK=TIMER",
|
status = MonSendBuffer(cntrData, "SICS SET TE_CHECK=TIMER", &self->buffer);
|
||||||
self->buffer.body, sizeof(self->buffer.body));
|
if (status != SUCCESS || strcasecmp(self->buffer.body, "OK") != 0) {
|
||||||
} else {
|
self->errorCode = /* TODO */ 0;
|
||||||
MonSend(cntrData, "SICS SET TE_CHECK=COUNTER",
|
return FAILURE;
|
||||||
self->buffer.body, sizeof(self->buffer.body));
|
}
|
||||||
|
} else {
|
||||||
|
status = MonSendBuffer(cntrData, "SICS SET TE_CHECK=COUNTER", &self->buffer);
|
||||||
|
if (status != SUCCESS || strcasecmp(self->buffer.body, "OK") != 0) {
|
||||||
|
self->errorCode = /* TODO */ 0;
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*@-duplicatequals@ for uint64 */
|
||||||
|
/*@-formattype@ for uint64 */
|
||||||
|
(void) snprintf(str, sizeof(str), "SICS SET TERMINAL=%llu",
|
||||||
|
(uint64) cntrData->fPreset);
|
||||||
|
/*@+formattype@*/
|
||||||
|
/*@+duplicatequals@*/
|
||||||
|
status = MonSendBuffer(cntrData, str, &self->buffer);
|
||||||
|
if (status != SUCCESS || strcasecmp(self->buffer.body, "OK") != 0) {
|
||||||
|
self->errorCode = /* TODO */ 0;
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
status = MonSendBuffer(cntrData, "SICS START", &self->buffer);
|
||||||
|
if (status != SUCCESS || strcasecmp(self->buffer.body, "OK") != 0) {
|
||||||
|
self->errorCode = /* TODO */ 0;
|
||||||
|
return FAILURE;
|
||||||
}
|
}
|
||||||
snprintf(str, sizeof(str), "SICS SET TERMINAL=%llu",
|
|
||||||
(unsigned long long) cntrData->fPreset);
|
|
||||||
MonSend(cntrData, str,
|
|
||||||
self->buffer.body, sizeof(self->buffer.body));
|
|
||||||
MonSend(cntrData, "SICS START",
|
|
||||||
self->buffer.body, sizeof(self->buffer.body));
|
|
||||||
self->state = HWBusy;
|
self->state = HWBusy;
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -335,13 +431,18 @@ static int MonStart(CounterDriver *cntrData) {
|
|||||||
/** \brief Pauses a counting operation
|
/** \brief Pauses a counting operation
|
||||||
*
|
*
|
||||||
* \param *cntrData provides access to a monitor's data
|
* \param *cntrData provides access to a monitor's data
|
||||||
|
* \return SUCCESS or FAILURE
|
||||||
|
*
|
||||||
|
* TODO: check if we should set the state to HWPause or just leave it till we
|
||||||
|
* get it back from the monitor.
|
||||||
*/
|
*/
|
||||||
static int MonPause(CounterDriver *cntrData) {
|
static int MonPause(CounterDriver *cntrData) {
|
||||||
BeamMon *self = NULL;
|
BeamMon *self = NULL;
|
||||||
|
int status;
|
||||||
|
|
||||||
self = (BeamMon *) cntrData->pData;
|
self = (BeamMon *) cntrData->pData;
|
||||||
if (MonSend(cntrData, "SICS PAUSE",
|
status = MonSendBuffer(cntrData, "SICS PAUSE", &self->buffer);
|
||||||
self->buffer.body, sizeof(self->buffer.body)) == SUCCESS) {
|
if (status == SUCCESS) {
|
||||||
self->state = HWPause;
|
self->state = HWPause;
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -351,13 +452,18 @@ static int MonPause(CounterDriver *cntrData) {
|
|||||||
/* \brief Continues a paused counting operation.
|
/* \brief Continues a paused counting operation.
|
||||||
*
|
*
|
||||||
* \param *cntrData provides access to a monitor's data
|
* \param *cntrData provides access to a monitor's data
|
||||||
|
* \return SUCCESS or FAILURE
|
||||||
|
*
|
||||||
|
* TODO: check if we should set the sate to HWBusy or just leave it till we
|
||||||
|
* get it back from the monitor.
|
||||||
*/
|
*/
|
||||||
static int MonContinue(CounterDriver *cntrData) {
|
static int MonContinue(CounterDriver *cntrData) {
|
||||||
BeamMon *self = NULL;
|
BeamMon *self = NULL;
|
||||||
|
int status;
|
||||||
|
|
||||||
self = (BeamMon *) cntrData->pData;
|
self = (BeamMon *) cntrData->pData;
|
||||||
if (MonSend(cntrData, "SICS CONTINUE",
|
status = MonSendBuffer(cntrData, "SICS CONTINUE", &self->buffer);
|
||||||
self->buffer.body, sizeof(self->buffer.body)) == SUCCESS) {
|
if (status == SUCCESS) {
|
||||||
self->state = HWBusy;
|
self->state = HWBusy;
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -366,14 +472,19 @@ static int MonContinue(CounterDriver *cntrData) {
|
|||||||
|
|
||||||
/** \brief Cancels a counting operation. This is an emergency stop used when interrupting an operation.
|
/** \brief Cancels a counting operation. This is an emergency stop used when interrupting an operation.
|
||||||
* \param *cntrData provides access to a monitor's data
|
* \param *cntrData provides access to a monitor's data
|
||||||
|
* \return SUCCESS or FAILURE
|
||||||
|
*
|
||||||
|
* TODO: check if we should set the sate to HWIdle or just leave it till we
|
||||||
|
* get it back from the monitor.
|
||||||
*/
|
*/
|
||||||
static int MonHalt(CounterDriver *cntrData) {
|
static int MonHalt(CounterDriver *cntrData) {
|
||||||
BeamMon *self = NULL;
|
BeamMon *self = NULL;
|
||||||
|
int status;
|
||||||
|
|
||||||
self = (BeamMon *) cntrData->pData;
|
self = (BeamMon *) cntrData->pData;
|
||||||
if (MonSend(cntrData, "SICS STOP",
|
status = MonSendBuffer(cntrData, "SICS STOP", &self->buffer);
|
||||||
self->buffer.body, sizeof(self->buffer.body)) == SUCCESS) {
|
if (status == SUCCESS) {
|
||||||
self->state = HWBusy;
|
self->state = HWIdle;
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
@@ -382,18 +493,21 @@ static int MonHalt(CounterDriver *cntrData) {
|
|||||||
/** \brief Reads the counter and the monitors in the lCounts array.
|
/** \brief Reads the counter and the monitors in the lCounts array.
|
||||||
*
|
*
|
||||||
* \param *cntrData provides access to a monitor's data
|
* \param *cntrData provides access to a monitor's data
|
||||||
|
* \return SUCCESS or FAILURE
|
||||||
*/
|
*/
|
||||||
static int MonReadValues(CounterDriver *cntrData) {
|
static int MonReadValues(CounterDriver *cntrData) {
|
||||||
BeamMon *self = NULL;
|
BeamMon *self = NULL;
|
||||||
|
int status;
|
||||||
|
|
||||||
flog('.', "MonReadValues");
|
flog('.', "MonReadValues");
|
||||||
self = (BeamMon *) cntrData->pData;
|
self = (BeamMon *) cntrData->pData;
|
||||||
if (MonSend(cntrData, "SICS READ",
|
status = MonSendBuffer(cntrData, "SICS READ", &self->buffer);
|
||||||
self->buffer.body, sizeof(self->buffer.body)) == SUCCESS) {
|
if (status == SUCCESS) {
|
||||||
HandleReport(cntrData, &self->buffer);
|
HandleReport(cntrData, &self->buffer);
|
||||||
lCounts[0] = self->counter_value;
|
cntrData->lCounts[0] = (long) self->counter_value; /* NOTE: truncation */
|
||||||
}
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* \brief Called when an error condition is reported by a counter operation.
|
/* \brief Called when an error condition is reported by a counter operation.
|
||||||
@@ -411,7 +525,7 @@ static int MonGetError(CounterDriver *cntrData, int *iCode, char *error, int iEr
|
|||||||
self = (BeamMon *) cntrData->pData;
|
self = (BeamMon *) cntrData->pData;
|
||||||
/* Allocate iErrLen bytes for error messages */
|
/* Allocate iErrLen bytes for error messages */
|
||||||
if (self->errorMsg == NULL) {
|
if (self->errorMsg == NULL) {
|
||||||
self->errorMsg = (char *) malloc(iErrLen);
|
self->errorMsg = (char *) malloc((size_t) iErrLen);
|
||||||
if (self->errorMsg == NULL) {
|
if (self->errorMsg == NULL) {
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
@@ -420,7 +534,9 @@ static int MonGetError(CounterDriver *cntrData, int *iCode, char *error, int iEr
|
|||||||
*iCode = self->errorCode;
|
*iCode = self->errorCode;
|
||||||
switch (*iCode) {
|
switch (*iCode) {
|
||||||
case 0:
|
case 0:
|
||||||
strncpy(error, "UNKNOWN ERROR: counterdriv did not set an errorcode.", iErrLen);
|
strncpy(error,
|
||||||
|
"UNKNOWN ERROR: counterdriv did not set an errorcode.",
|
||||||
|
(size_t) iErrLen);
|
||||||
break;
|
break;
|
||||||
case NOTCONNECTED:
|
case NOTCONNECTED:
|
||||||
case TIMEOUT:
|
case TIMEOUT:
|
||||||
@@ -430,7 +546,9 @@ static int MonGetError(CounterDriver *cntrData, int *iCode, char *error, int iEr
|
|||||||
getRS232Error(*iCode, error, iErrLen);
|
getRS232Error(*iCode, error, iErrLen);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
snprintf(error, iErrLen, "Unknown error code: %d, returned from counterdriv", *iCode);
|
(void) snprintf(error, (size_t) iErrLen,
|
||||||
|
"Unknown error code: %d, returned from counterdriv",
|
||||||
|
*iCode);
|
||||||
}
|
}
|
||||||
self->errorCode = 0;
|
self->errorCode = 0;
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
@@ -453,8 +571,9 @@ static int MonTryAndFixIt(CounterDriver *cntrData, int iCode) {
|
|||||||
|
|
||||||
switch(iCode){
|
switch(iCode){
|
||||||
case NOTCONNECTED:
|
case NOTCONNECTED:
|
||||||
initRS232(self->controller);
|
if (initRS232(self->controller) == 1)
|
||||||
return COREDO;
|
return COREDO;
|
||||||
|
return COTERM;
|
||||||
case BADSEND:
|
case BADSEND:
|
||||||
case TIMEOUT:
|
case TIMEOUT:
|
||||||
case BADMEMORY: /* Won't happen if MonConnect sets the send terminator */
|
case BADMEMORY: /* Won't happen if MonConnect sets the send terminator */
|
||||||
@@ -473,7 +592,7 @@ static int MonTryAndFixIt(CounterDriver *cntrData, int iCode) {
|
|||||||
static int MonSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
|
static int MonSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
|
||||||
BeamMon *self = NULL;
|
BeamMon *self = NULL;
|
||||||
char str[100];
|
char str[100];
|
||||||
snprintf(str, 100, "MonSet(%s, %d, %f)", name, iCter, fVal);
|
(void) snprintf(str, 100, "MonSet(%s, %d, %f)", name, iCter, fVal);
|
||||||
flog('.', str);
|
flog('.', str);
|
||||||
|
|
||||||
self = (BeamMon *) cntrData->pData;
|
self = (BeamMon *) cntrData->pData;
|
||||||
@@ -487,6 +606,7 @@ static int MonSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
|
|||||||
|
|
||||||
static int MonGet(CounterDriver *cntrData, char *name, int iCter, float *fVal) {
|
static int MonGet(CounterDriver *cntrData, char *name, int iCter, float *fVal) {
|
||||||
BeamMon *self = NULL;
|
BeamMon *self = NULL;
|
||||||
|
char str[100];
|
||||||
|
|
||||||
self = (BeamMon *) cntrData->pData;
|
self = (BeamMon *) cntrData->pData;
|
||||||
if(strcasecmp(name,"threshold") == 0){
|
if(strcasecmp(name,"threshold") == 0){
|
||||||
@@ -495,35 +615,28 @@ static int MonGet(CounterDriver *cntrData, char *name, int iCter, float *fVal) {
|
|||||||
}
|
}
|
||||||
/* TODO*/
|
/* TODO*/
|
||||||
|
|
||||||
char str[100];
|
(void) snprintf(str, 100, "MonGet(%s, %d, %f)", name, iCter, *fVal);
|
||||||
snprintf(str, 100, "MonGet(%s, %d, %f)", name, iCter, *fVal);
|
|
||||||
flog('.', str);
|
flog('.', str);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int MonSend(CounterDriver *cntrData, char *pText, char *pReply, int iReplyLen) {
|
static void KillMon(/*@null@*/ pCounterDriver cntrData) {
|
||||||
BeamMon *self = NULL;
|
if (cntrData != NULL) {
|
||||||
int status;
|
if (cntrData->pData != NULL) {
|
||||||
|
pBeamMon self = (pBeamMon) cntrData->pData;
|
||||||
self = (BeamMon *) cntrData->pData;
|
if (self->host) {
|
||||||
MonDrainInput(cntrData);
|
|
||||||
MonWrite(self, pText);
|
|
||||||
if ((status = MonRead(self, pReply, &iReplyLen)) == SUCCESS)
|
|
||||||
{
|
|
||||||
pReply[iReplyLen] = '\0';
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void KillMon(pCounterDriver cntrData) {
|
|
||||||
pBeamMon self = NULL;
|
|
||||||
self = (pBeamMon) cntrData->pData;
|
|
||||||
if (self) {
|
|
||||||
if (self->host)
|
|
||||||
free(self->host);
|
free(self->host);
|
||||||
if (self->errorMsg)
|
self->host = NULL;
|
||||||
|
}
|
||||||
|
if (self->errorMsg) {
|
||||||
free(self->errorMsg);
|
free(self->errorMsg);
|
||||||
|
self->errorMsg = NULL;
|
||||||
|
}
|
||||||
|
KillRS232(self->controller);
|
||||||
|
free(cntrData->pData);
|
||||||
|
cntrData->pData = NULL;
|
||||||
|
}
|
||||||
|
/* TODO free(cntrData); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,17 +654,17 @@ static void KillMon(pCounterDriver cntrData) {
|
|||||||
|
|
||||||
controller=createRS232(host,port);
|
controller=createRS232(host,port);
|
||||||
if (controller==NULL) {
|
if (controller==NULL) {
|
||||||
snprintf(pError, ERRLEN,
|
(void) snprintf(pError, ERRLEN,
|
||||||
"ERROR: failed to create controller for %s at port %d",
|
"ERROR: failed to create controller for %s at port %d",
|
||||||
host, port);
|
host, port);
|
||||||
SCWrite(pCon,pError,eError);
|
(void) SCWrite(pCon,pError,eError);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if ( initRS232(controller) != 1) {
|
if ( initRS232(controller) != 1) {
|
||||||
snprintf(pError, ERRLEN,
|
(void) snprintf(pError, ERRLEN,
|
||||||
"ERROR: failed to connect to %s at port %d",
|
"ERROR: failed to connect to %s at port %d",
|
||||||
host, port);
|
host, port);
|
||||||
SCWrite(pCon,pError,eError);
|
(void) SCWrite(pCon,pError,eError);
|
||||||
KillRS232(controller);
|
KillRS232(controller);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -614,13 +727,19 @@ static void KillMon(pCounterDriver cntrData) {
|
|||||||
KillMon(pCntDriv);
|
KillMon(pCntDriv);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sscanf(pPtr,"%d", &newCtr->iPort);
|
(void) sscanf(pPtr,"%d", &newCtr->iPort);
|
||||||
|
|
||||||
if ((pPtr=getParam(pCon, interp, params,"host",1)) == NULL) {
|
if ((pPtr=getParam(pCon, interp, params,"host",1)) == NULL) {
|
||||||
KillMon(pCntDriv);
|
KillMon(pCntDriv);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
/*@-mustfreeonly@ host = NULL after BeamMon is created */
|
||||||
newCtr->host = strdup(pPtr);
|
newCtr->host = strdup(pPtr);
|
||||||
|
/*@+mustfreeonly@*/
|
||||||
|
|
||||||
|
/*@-mustfreeonly@ controller = NULL after BeamMon is created */
|
||||||
newCtr->controller = MonConnect(pCon, newCtr->host, newCtr->iPort);
|
newCtr->controller = MonConnect(pCon, newCtr->host, newCtr->iPort);
|
||||||
|
/*@+mustfreeonly@*/
|
||||||
|
|
||||||
newCtr->dummy_threshold = 1.7e6;
|
newCtr->dummy_threshold = 1.7e6;
|
||||||
return pCntDriv;
|
return pCntDriv;
|
||||||
|
|||||||
Reference in New Issue
Block a user