The camera driver can now send meta data such as the motor positions to the camera server.

An auxiliary command has been added so we can set string values on the camera driver for the meta data.
This commit is contained in:
Ferdi Franceschini
2014-07-31 15:45:03 +10:00
parent 9b965e6313
commit fdbb0456ad
2 changed files with 328 additions and 56 deletions

View File

@ -62,7 +62,7 @@
TR(ECA_MLTI_OFF, "take multi off") \
TR(ECA_GET_STATUS, "get status") \
TR(ECA_GET_STATE, "get state") \
TE(ECA_CFG, "send configuration")
TE(ECA_CFG, "update camera settings, file configuration and meta data")
#define CAMERA_MSGS_TABLE \
TR(ECA_START, "StartTime") \

View File

@ -8,6 +8,8 @@
*
* Copyright: see file Copyright.txt
*/
#include <limits.h>
#include <errno.h>
#include <string.h>
#include <sics.h>
#include <obdes.h>
@ -17,8 +19,12 @@
#include <math.h>
#include "camera.h"
#define NAMELEN 32
#define IFMTLEN 4
#define ERRLEN 256
#define MSGLEN 512
#define MAX_META_COUNT 32
#define MAX_SCANVAR_COUNT 16
enum camstates {idle, acquiring, processing, saving};
#define CAMDRIV_ERRTABLE \
@ -85,10 +91,20 @@ static char *flipcmdstr[] = {FLIP_TABLE, NULL};
#undef TR
#undef TE
// Camera get/set commands: ['status', 'info', 'state', 'camera', 'meta', 'file']
#define ECMDSTART 0
#define EGETSTART 100
#define ESETSTART 200
#define UPDATE_SETTINGS_CFG 1
#define CLEAR_META_CFG 2
#define UPDATE_META_CFG 4
#define UPDATE_SCANVAR_CFG 8
#define UPDATE_FILE_CFG 16
typedef struct {
char path[MSGLEN];
char basename[MSGLEN];
long startnumber;
char imageformat[IFMTLEN];
char experimentdetail[MSGLEN];
} filecfg_t;
typedef struct {
float clockMHz;
float bin;
@ -105,18 +121,17 @@ typedef struct {
float shopt;
float shclt;
int updatecfg;
filecfg_t file;
char meta_list[MAX_META_COUNT][MSGLEN];
char scanvar_list[MAX_SCANVAR_COUNT][NAMELEN];
pDummy scanvar_dummy[MAX_SCANVAR_COUNT];
pIDrivable pscanvar[MAX_SCANVAR_COUNT];
int meta_count;
int scanvar_count;
} camcfg_t;
typedef struct {
char path[MSGLEN];
char basename[MSGLEN];
int startnumber;
char imageformat[MSGLEN];
char experimentdetail[MSGLEN];
int updatecfg;
} filecfg_t;
typedef struct {
pObjectDescriptor pDes;
int debug;
char *asynq;
camsm_t state_machine;
@ -124,8 +139,8 @@ typedef struct {
int status;
enum errcodes camError;
camcfg_t camera;
/* filecfg_t file;*/
pAsyncUnit asyncUnit;
SicsInterp *pSics;
} CamObj;
/* Camera communications and protocol handlers */
@ -134,6 +149,21 @@ static int cb_state_timer(void *ctx, int mode);
static int cb_getstate(pAsyncTxn txn);
static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal);
/* if emsg == NULL conversion OK else if emsg == num not an integer else emsg == error message */
long getlong(char *num, char *emsg) {
long val = 0;
char *endptr;
errno = 0;
emsg = NULL;
val = strtol(num, &endptr, 10);
if ( (errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0) )
emsg = strerror(errno);
if (endptr == num)
emsg = num;
return val;
}
static void CAM_Notify(void* context, int event) {
CamObj *self = (CamObj *) context;
@ -215,10 +245,10 @@ static int CamGetStatus(CounterDriver *cntrData, float *fControl) {
* \param ev_sym, input event
*/
static void run_sm(CamObj *self, enum event_codes ev_sym) {
char sscur[SSLEN+1], ssnext[SSLEN+1], esout[ESLEN+1], message[MSGLEN+1];
char *sscur, *ssnext, *esout, message[MSGLEN+1];
if (self->debug) {
strncpy(sscur, strstate(self->state_machine.Sc), SSLEN);
sscur = strstate(self->state_machine.Sc);
snprintf(message, MSGLEN, "DEBUG:(run_sm) Scurr:%s Ei:%s",
sscur,event_names[ev_sym]);
SICSLogWrite(message, eLog);
@ -227,9 +257,9 @@ static void run_sm(CamObj *self, enum event_codes ev_sym) {
camdriv_input(self, &self->state_machine, ev_sym);
if (self->debug) {
strncpy(ssnext, strstate(self->state_machine.Sc), SSLEN);
strncpy(esout, strevent(self->state_machine.Eo), ESLEN);
snprintf(message, MSGLEN, "DEBUG:(run_sm) Snext:%s Eo:%s", ssnext,esout);
ssnext = strstate(self->state_machine.Sc), SSLEN;
esout = strevent(self->state_machine.Eo), ESLEN;
snprintf(message, MSGLEN, "DEBUG:(run_sm) Snext:%s Eo:%s", ssnext, esout);
SICSLogWrite(message, eLog);
}
}
@ -277,7 +307,7 @@ static int CamHalt(CounterDriver *cntrData) {
}
return 1;
}
/* TODO what should the counter data be set to? Total intensity? */
/* FIXME what should the counter data be set to? Total intensity? */
static int CamReadValues(CounterDriver *cntrData) {
int status, iReplyLen=MSGLEN;
char *cmd="TODO ", pReply[MSGLEN];
@ -358,7 +388,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
case CLOCK:
if (fVal > 0) {
camdriv->camera.clockMHz = fVal;
camdriv->camera.updatecfg = 1;
camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG;
} else {
return 0;
}
@ -366,7 +396,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
case BIN:
if (fVal > 0) {
camdriv->camera.bin = fVal;
camdriv->camera.updatecfg = 1;
camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG;
} else {
return 0;
}
@ -374,7 +404,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
case SIZE:
if (fVal > 0) {
camdriv->camera.size = fVal;
camdriv->camera.updatecfg = 1;
camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG;
} else {
return 0;
}
@ -382,7 +412,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
case GAIN:
if (fVal > 0) {
camdriv->camera.gain = fVal;
camdriv->camera.updatecfg = 1;
camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG;
} else {
return 0;
}
@ -399,7 +429,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
case INVFV:
case INVFHV:
camdriv->camera.flip = flip;
camdriv->camera.updatecfg = 1;
camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG;
break;
default:
return 0;
@ -409,7 +439,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
case XSTART:
if (fVal > 0) {
camdriv->camera.xstart = fVal;
camdriv->camera.updatecfg = 1;
camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG;
} else {
return 0;
}
@ -417,7 +447,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
case YSTART:
if (fVal > 0) {
camdriv->camera.ystart = fVal;
camdriv->camera.updatecfg = 1;
camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG;
} else {
return 0;
}
@ -425,7 +455,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
case XEND:
if (fVal > 0) {
camdriv->camera.xend = fVal;
camdriv->camera.updatecfg = 1;
camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG;
} else {
return 0;
}
@ -433,7 +463,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
case YEND:
if (fVal > 0) {
camdriv->camera.yend = fVal;
camdriv->camera.updatecfg = 1;
camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG;
} else {
return 0;
}
@ -441,19 +471,19 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
case EXPOSURE:
if (fVal > 0) {
camdriv->camera.exposure = fVal;
camdriv->camera.updatecfg = 1;
camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG;
} else {
return 0;
}
break;
case TEMP:
camdriv->camera.temp = fVal;
camdriv->camera.updatecfg = 1;
camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG;
break;
case THRESH:
if (fVal > 0) {
camdriv->camera.thresh = fVal;
camdriv->camera.updatecfg = 1;
camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG;
} else {
return 0;
}
@ -461,7 +491,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
case SHOPT:
if (fVal > 0) {
camdriv->camera.shopt = fVal;
camdriv->camera.updatecfg = 1;
camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG;
} else {
return 0;
}
@ -469,7 +499,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
case SHCLT:
if (fVal > 0) {
camdriv->camera.shclt = fVal;
camdriv->camera.updatecfg = 1;
camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG;
} else {
return 0;
}
@ -569,7 +599,6 @@ static int CamSend(CounterDriver *cntrData, char *pText, char *pReply, int iRepl
static int cb_shotcmd(pAsyncTxn txn) {
CamObj *self = (CamObj *) txn->cntx;
char *resp = txn->inp_buf, message[MSGLEN+1];
enum event_codes cd_sym;
if (self->debug) {
snprintf(message, MSGLEN, "DEBUG:(cb_shotcmd) Camera reply: %s", resp);
@ -587,30 +616,44 @@ static int cb_shotcmd(pAsyncTxn txn) {
* it should be fed back into the state transition function.
*/
int camdriv_out(void *me, event_t Eo) {
int len, feedback = 0;
int i, len, pend=0;
char cmd[MSGLEN]="", logmsg[MSGLEN+1]="";
float clock;
float clock, fVal;
CamObj *self = (CamObj *)me;
if (Eo.ca) {
/* send command to camera */
if (self->debug) {
snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:Eo.ca): ev=%s, output=%s\n",
event_names[Eo.ca], event_signatures[Eo.ca]);
SICSLogWrite(logmsg, eLog);
}
switch (Eo.ca) {
case ECA_TK_SHOT:
len = strlen(event_signatures[ECA_TK_SHOT]);
strncpy(cmd, event_signatures[ECA_TK_SHOT], len);
len = strlen(cmd);
AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN);
break;
case ECA_MLTI_ON:
len = strlen(event_signatures[ECA_MLTI_ON]);
strncpy(cmd, event_signatures[ECA_MLTI_ON], len);
len = strlen(cmd);
AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN);
break;
case ECA_MLTI_OFF:
len = strlen(event_signatures[ECA_MLTI_OFF]);
strncpy(cmd, event_signatures[ECA_MLTI_OFF], len);
len = strlen(cmd);
AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN);
break;
case ECA_CFG:
if(self->camera.updatecfg) {
/* TODO Should we retry sending a command if AsyncUnitSendTxn fails?
* The driver should abort the shot and then try to send the
* configuration the next time a shot is taken. */
if( (self->camera.updatecfg & UPDATE_SETTINGS_CFG) == UPDATE_SETTINGS_CFG) {
clock = self->camera.clockMHz;
sprintf(cmd,
snprintf(cmd, MSGLEN,
"set camera,clock=%.*fmhz,bin=%dx,size=%d,gain=%dxhs,flip=%s,xstart=%d,ystart=%d,xend=%d,yend=%d,exposure=%f,temperature=%f,threshold=%d,shutteropentime=%d,shutterclosetime=%d",
clock>=1 ? 0 : 1, clock, (int)self->camera.bin, (int)self->camera.size,
(int)self->camera.gain, flipcmdstr[self->camera.flip],
@ -620,7 +663,59 @@ int camdriv_out(void *me, event_t Eo) {
(int)self->camera.shclt
);
len = strlen(cmd);
self->camera.updatecfg = 0;
self->camera.updatecfg &= ~UPDATE_SETTINGS_CFG;
if (self->debug) {
snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:UPDATE_SETTINGS_CFG): cmd=%s\n", cmd);
SICSLogWrite(logmsg, eLog);
}
AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN);
}
if( (self->camera.updatecfg & CLEAR_META_CFG) == CLEAR_META_CFG) {
snprintf(cmd, MSGLEN, "clear meta");
len = strlen(cmd);
if (self->debug) {
snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:CLEAR_META_CFG): cmd=%s\n", cmd);
SICSLogWrite(logmsg, eLog);
}
AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN);
}
if( (self->camera.updatecfg & UPDATE_META_CFG) == UPDATE_META_CFG) {
//TODO concatenate the meta_list into a comma separated string and send it in MSGLEN chunks.
for (i=0; i < self->camera.meta_count && pend < MSGLEN; i++) {
pend = sprintf(cmd, "set meta,");
pend += snprintf(&cmd[pend], MSGLEN, "%s", self->camera.meta_list[i]);
len = strlen(cmd);
if (self->debug) {
snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:UPDATE_META_CFG): cmd=%s\n", cmd);
SICSLogWrite(logmsg, eLog);
}
AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN);
}
}
if( (self->camera.updatecfg & UPDATE_SCANVAR_CFG) == UPDATE_SCANVAR_CFG) {
pend = sprintf(cmd, "set meta");
//TODO Send in MSGLEN chunks even though the string may never exceed MSGLEN
for (i=0; i < self->camera.scanvar_count && pend < MSGLEN; i++) {
fVal = self->camera.pscanvar[i]->GetValue(self->camera.scanvar_dummy[i], pServ->dummyCon);
pend += snprintf(&cmd[pend], MSGLEN, ",%s=%f", self->camera.scanvar_list[i], fVal);
}
len = strlen(cmd);
if (self->debug) {
snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:UPDATE_SCANVAR_CFG): cmd=%s\n", cmd);
SICSLogWrite(logmsg, eLog);
}
AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN);
}
if( (self->camera.updatecfg & UPDATE_FILE_CFG) == UPDATE_FILE_CFG) {
snprintf(cmd, MSGLEN, "set file,path=%s,basename=%s,startnumber=%ld,imageformat=%s,experimentdetail=%s",
self->camera.file.path, self->camera.file.basename, self->camera.file.startnumber, self->camera.file.imageformat,self->camera.file.experimentdetail);
len = strlen(cmd);
if (self->debug) {
snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:UPDATE_FILE_CFG): cmd=%s\n", cmd);
SICSLogWrite(logmsg, eLog);
}
AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN);
self->camera.updatecfg &= ~UPDATE_FILE_CFG;
}
break;
default:
@ -628,12 +723,6 @@ int camdriv_out(void *me, event_t Eo) {
SICSLogWrite(logmsg, eLogError);
return -1;
}
AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN);
if (self->debug) {
snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:Eo.ca): ev=%s, output=%s\n",
event_names[Eo.ca], event_signatures[Eo.ca]);
SICSLogWrite(logmsg, eLog);
}
return -1;
}
if (Eo.cm) {
@ -650,6 +739,11 @@ int camdriv_out(void *me, event_t Eo) {
}
if (Eo.dr) {
/* send msg to SICS */
if (self->debug) {
snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out): ev=%s, output=%s\n",
event_names[Eo.dr], event_signatures[Eo.dr]);
SICSLogWrite(logmsg, eLog);
}
switch (Eo.dr) {
case EDR_IDLE:
self->status = HWIdle;
@ -665,11 +759,6 @@ int camdriv_out(void *me, event_t Eo) {
SICSLogWrite(logmsg, eLogError);
return -1;
}
if (self->debug) {
snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out): ev=%s, output=%s\n",
event_names[Eo.dr], event_signatures[Eo.dr]);
SICSLogWrite(logmsg, eLog);
}
return -1;
}
if (Eo.cl) {
@ -709,7 +798,7 @@ static int cb_state_timer(void *ctx, int mode) {
static int cb_getstate(pAsyncTxn txn) {
CamObj *self = (CamObj *) txn->cntx;
char *resp = txn->inp_buf, message[MSGLEN+1];
int len = txn->inp_idx, ret=1, time_rem, time_tot;
int ret=1, time_rem, time_tot;
enum event_codes ca_sym, cm_sym;
@ -731,9 +820,182 @@ static int cb_getstate(pAsyncTxn txn) {
return ret;
}
/* Auxiliary Camera Driver commands */
int cmd_code(char **cmd_list, char *cmd) {
int i;
for (i=0; cmd_list[i] != NULL; i++)
if (strcasecmp(cmd_list[i], cmd) == 0)
return i;
return -1;
}
int file_cmd(CamObj *camdriv, SConnection *pCon, char *subcmd, char *data) {
int i, subcmd_code, retval = 1;
long numval;
enum file_subcmd_codes {PATH, BASENAME, IMAGEFMT, STARTNUM, EXPDETAIL};
char *file_subcmd_names[] = {"path", "name", "format", "startnumber", "detail", NULL};
char *glemsg = NULL, emsg[MSGLEN];
if ( (subcmd_code = cmd_code(file_subcmd_names, subcmd)) == -1) {
return 0;
}
switch (subcmd_code) {
case PATH:
snprintf(camdriv->camera.file.path, MSGLEN, "%s", data);
break;
case BASENAME:
snprintf(camdriv->camera.file.basename, MSGLEN, "%s", data);
break;
case STARTNUM:
numval = getlong(data, glemsg);
if (glemsg == NULL) {
camdriv->camera.file.startnumber = numval;
} else if (glemsg == data) {
snprintf(emsg, MSGLEN, "CAM:(file_cmd) %s is not an integer", data);
SCWrite(pCon, emsg, eError);
retval = 0;
} else {
snprintf(emsg, MSGLEN, "CAM:(file_cmd) %s", glemsg);
SCWrite(pCon, emsg, eError);
retval = 0;
}
break;
case IMAGEFMT:
if (strcasecmp(data, "tif") == 0) {
for (i=0; data[i]; i++) {
data[i] = tolower(data[i]);
}
snprintf(camdriv->camera.file.imageformat, IFMTLEN, "%s", data);
} else {
retval = 0;
}
break;
case EXPDETAIL:
snprintf(camdriv->camera.file.experimentdetail, MSGLEN, "%s", data);
break;
default:
retval = 0;
}
return retval;
}
/**
* \brief Auxiliary command interface which gets around type and string length
* limitations of the CountAction command.
*/
int CamAuxCmd(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) {
char *cmd = NULL;
char message[MSGLEN];
enum auxcmd_codes {CLEAR_META, META, FILECMD, SCANVAR, MOTOR};
char *auxcmd_names[] = {"clearmeta", "meta", "file", "scanvar", "motor", NULL};
int i, code, retval = 1, pend=0;
CamObj *camdriv = (CamObj *)pData;
CommandList *pCom = NULL;
pIDrivable pDriv = NULL;
pDummy pDumData = NULL;
if (argc < 2) {
snprintf(message, MSGLEN, "CAM: You must specify a command");
SCWrite(pCon, message, eError);
return 0;
}
if ( (code = cmd_code(auxcmd_names, argv[1])) == -1 ) {
snprintf(message, MSGLEN, "CAM: %s is not a valid command", argv[1]);
SCWrite(pCon, message, eError);
retval = 0;
goto END;
}
switch (code) {
case CLEAR_META:
camdriv->camera.meta_count = 0;
camdriv->camera.scanvar_count = 0;
camdriv->camera.updatecfg |= CLEAR_META_CFG;
camdriv->camera.updatecfg &= ~UPDATE_META_CFG;
camdriv->camera.updatecfg &= ~UPDATE_SCANVAR_CFG;
break;
case META:
if (argc < 3) {
snprintf(message, MSGLEN, "CAM: Insufficient arguments, the META command requires name=val data");
SCWrite(pCon, message, eError);
retval = 0;
goto END;
}
if (camdriv->camera.meta_count < MAX_META_COUNT) {
for (i=2; i < argc; i++) {
pend += snprintf(&(camdriv->camera.meta_list[camdriv->camera.meta_count][pend]), MSGLEN, "%s ", argv[i]);
}
camdriv->camera.meta_count++;
camdriv->camera.updatecfg |= UPDATE_META_CFG;
} else {
goto END;
}
break;
case SCANVAR:
case MOTOR:
if (argc < 3) {
snprintf(message, MSGLEN, "CAM: Insufficient arguments, the MOTOR/SCANVAR command requires the name of something you can drive like a motor or environment control");
SCWrite(pCon, message, eError);
retval = 0;
goto END;
}
if (camdriv->camera.scanvar_count < MAX_SCANVAR_COUNT) {
pCom = FindCommand(pSics, argv[2]);
if (!pCom) {
snprintf(message, MSGLEN, "CAM: There is no command object for a driveable with this name %s", argv[2]);
SCWrite(pCon, message, eError);
retval = 0;
goto END;
}
pDumData = (pDummy) pCom->pData;
if (!pDumData) {
snprintf(message, MSGLEN, "CAM: There is no data for the command object of a driveable with this name %s", argv[2]);
SCWrite(pCon, message, eError);
retval = 0;
goto END;
}
pDriv = (pIDrivable) pDumData->pDescriptor->GetInterface(pDumData, DRIVEID);
if (!pDriv) {
snprintf(message, MSGLEN, "CAM: %s is not a driveable object", argv[2]);
SCWrite(pCon, message, eError);
retval = 0;
goto END;
}
camdriv->camera.scanvar_dummy[camdriv->camera.scanvar_count] = pDumData;
camdriv->camera.pscanvar[camdriv->camera.scanvar_count] = pDriv;
snprintf(camdriv->camera.scanvar_list[camdriv->camera.scanvar_count++], NAMELEN, "%s", argv[2]);
camdriv->camera.updatecfg |= UPDATE_SCANVAR_CFG;
} else {
snprintf(message, MSGLEN, "CAM: Exceeded maximum number (%d) of driveable objects", MAX_SCANVAR_COUNT);
SCWrite(pCon, message, eError);
retval = 0;
goto END;
}
break;
case FILECMD:
if (argc < 4) {
snprintf(message, MSGLEN, "CAM: Insufficient arguments for the FILE command");
SCWrite(pCon, message, eError);
retval = 0;
goto END;
}
if (file_cmd(camdriv, pCon, argv[2], argv[3]))
camdriv->camera.updatecfg |= UPDATE_FILE_CFG;
else {
snprintf(message, MSGLEN, "CAM: Failed to create camera file configuration");
SCWrite(pCon, message, eError);
retval = 0;
goto END;
}
break;
}
END:
if (cmd != NULL)
free(cmd);
return retval;
}
pCounterDriver CreateCam(SConnection *pCon, char *name, char *asynq) {
char msg[ERRLEN], cmd[MSGLEN], reply[MSGLEN];
int len, reply_len;
char msg[ERRLEN], cmd[MSGLEN], auxcmd[NAMELEN];
int len;
state_t start_state = {.cl=SCL_RDY, .cm=SCM_IDLE, .dr=SDR_IDLE};
pCounterDriver pCntDriv = NULL;
@ -741,6 +1003,7 @@ pCounterDriver CreateCam(SConnection *pCon, char *name, char *asynq) {
pNewCam = (CamObj *) malloc(sizeof(CamObj));
memset(pNewCam, 0, sizeof(CamObj));
pNewCam->pDes = CreateDescriptor("CameraCommandObject");
STset(&pNewCam->state_machine.Sc, start_state);
EVclr(&pNewCam->state_machine.Eo);
pNewCam->state_machine.output_fn = camdriv_out;
@ -749,8 +1012,14 @@ pCounterDriver CreateCam(SConnection *pCon, char *name, char *asynq) {
pNewCam->status = HWIdle;
pNewCam->camError = ENONE;
pNewCam->debug = 1;
pNewCam->camera.updatecfg = 1;
pNewCam->camera.updatecfg = 0;
pNewCam->camera.meta_count = 0;
pNewCam->camera.scanvar_count = 0;
pNewCam->camera.file.startnumber = 1;
snprintf(pNewCam->camera.file.imageformat, IFMTLEN, "tif");
pNewCam->camera.file.experimentdetail[0] = '\0';
pNewCam->asynq = strdup(asynq);
pNewCam->pSics = pServ->pSics;
if (!AsyncUnitCreate(asynq, &pNewCam->asyncUnit)) {
snprintf(msg, ERRLEN, "CAM:AsyncQueue %s has not been defined", asynq);
@ -783,5 +1052,8 @@ pCounterDriver CreateCam(SConnection *pCon, char *name, char *asynq) {
len = strlen(event_signatures[ECA_GET_STATE]);
strncpy(cmd, event_signatures[ECA_GET_STATE], len);
NetWatchRegisterTimerPeriodic(&pNewCam->state_timer, 2000, 500, cb_state_timer, pNewCam);
snprintf(auxcmd, NAMELEN, "%s_cmd", name);
AddCommand(pNewCam->pSics, auxcmd, CamAuxCmd, NULL, pNewCam);
return pCntDriv;
}