Added command latch ready event and camera upload configuration event.

The camera driver will now upload the exposure time when it's called from a scan object.
The output function now returns events which are not targeted at the camera or SICS
so that they can be fed back into the state transition function.
The input event handler (camera.c:camdriv_input) now feeds output events back into the
transition function.
This commit is contained in:
Ferdi Franceschini
2014-07-24 12:35:47 +10:00
parent a62a284372
commit 67a3a198ac
4 changed files with 153 additions and 105 deletions

View File

@@ -132,6 +132,7 @@ typedef struct {
static pAsyncProtocol CAM_Protocol = NULL;
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);
static void CAM_Notify(void* context, int event) {
CamObj *self = (CamObj *) context;
@@ -216,76 +217,23 @@ static int CamGetStatus(CounterDriver *cntrData, float *fControl) {
static void run_sm(CamObj *self, enum event_codes ev_sym) {
char sscur[SSLEN+1], ssnext[SSLEN+1], esout[ESLEN+1], message[MSGLEN+1];
if (self->debug)
if (self->debug) {
strncpy(sscur, strstate(self->state_machine.Sc), SSLEN);
snprintf(message, MSGLEN, "DEBUG:(run_sm) Scurr:%s Ei:%s",
sscur,event_names[ev_sym]);
SICSLogWrite(message, eLog);
}
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) Scurr:%s Ei:%s",
sscur,event_names[ev_sym]);
SICSLogWrite(message, eLog);
snprintf(message, MSGLEN, "DEBUG:(run_sm) Snext:%s Eo:%s", ssnext,esout);
SICSLogWrite(message, eLog);
}
}
/* \brief sendcfg, Send the camera configuration to the camera server
*/
int sendcfg(CamObj *self) {
int status, replen=MSGLEN;
char reply[MSGLEN+1], logmsg[MSGLEN+1];
char cfgCmd[MSGLEN+1];
float clock = self->camera.clockMHz;
if(self->camera.updatecfg) {
sprintf(cfgCmd,
"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],
(int)self->camera.xstart, (int)self->camera.ystart,
(int)self->camera.xend, (int)self->camera.yend, self->camera.exposure,
self->camera.temp, (int)self->camera.thresh, (int)self->camera.shopt,
(int)self->camera.shclt
);
status = AsyncUnitTransact(self->asyncUnit, cfgCmd, strlen(cfgCmd), reply, &replen);
if (status <= 0)
return 0;
else
if (strncmp("OK", reply, 2) == 0)
return 1;
else {
snprintf(logmsg, MSGLEN, "CAM:(sendcfg) set camera reply=%s", reply);
SICSLogWrite(logmsg, eLogError);
return 0;
}
}
/* TBD, other fields to be set
if(self->file.updatecfg) {
sprintf(cfgCmd, "set camera, path=%s,basename=%s,startnumber=%d,imageformat=%s,experimentdetail=%s",
self->file.path,
self->file.basename,
self->file.startnumber,
self->file.imageformat, self->file.experimentdetail);
status = AsyncUnitTransact(self->asyncUnit, cfgCmd, strlen(cfgCmd), reply, &replen);
if (status <= 0)
return 0;
else
if (strncmp("OK", reply, 2) == 0)
return 1;
else {
snprintf(logmsg, MSGLEN, "CAM:(sendcfg) set file reply=%s", reply);
SICSLogWrite(logmsg, eLogError);
return 0;
}
} */
}
/* Called by the scan command and via the count and countnb subcommands of a
* counter object. Will update the configuration if necessary.
*/
@@ -295,18 +243,12 @@ static int CamStart(CounterDriver *cntrData) {
char logmsg[MSGLEN+1];
self = cntrData->pData;
/* Send the updated configuration to the camera server if it has been changed
* on SICS since the last shot was taken. */
if (self->camera.updatecfg) {
if (sendcfg(self) == 0) {
snprintf(logmsg, MSGLEN, "CAM:(CamStart) Failed to upload configuration");
SICSLogWrite(logmsg, eLogError);
return 0;
}
self->camera.updatecfg = 0;
if (self->debug) {
snprintf(logmsg, MSGLEN, "DEBUG:(CamStart): preset=%f\n",cntrData->fPreset);
SICSLogWrite(logmsg, eLog);
}
CamSet(cntrData, "exposure", 0, cntrData->fPreset);
if (self->state_machine.multi) {
cd_sym = ECD_MLTI_ON;
} else {
@@ -324,9 +266,13 @@ static int CamContinue(CounterDriver *cntrData) {
}
static int CamHalt(CounterDriver *cntrData) {
CamObj *self = cntrData->pData;
state_t start_state = {.cl=SCL_RDY, .cm=SCM_IDLE, .dr=SDR_IDLE};
if (self->state_machine.multi) {
run_sm(self, ECD_MLTI_OFF);
} else {
STset(&self->state_machine.Sc, start_state);
EVclr(&self->state_machine.Eo);
}
return 1;
}
@@ -618,6 +564,10 @@ static int cb_shotcmd(pAsyncTxn txn) {
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);
SICSLogWrite(message, eLog);
}
if (strncmp(resp, "OK", 2) != 0) {
self->camError = EFAIL;
return 0;
@@ -625,9 +575,14 @@ static int cb_shotcmd(pAsyncTxn txn) {
return 1;
}
/**
* \brief Decides if an output message is targeted at the camera or SICS or if
* it should be fed back into the state transition function.
*/
int camdriv_out(void *me, event_t Eo) {
int len;
int len, feedback = 0;
char cmd[MSGLEN]="", logmsg[MSGLEN+1]="";
float clock;
CamObj *self = (CamObj *)me;
if (Eo.ca) {
@@ -645,10 +600,26 @@ int camdriv_out(void *me, event_t Eo) {
len = strlen(event_signatures[ECA_MLTI_OFF]);
strncpy(cmd, event_signatures[ECA_MLTI_OFF], len);
break;
case ECA_CFG:
if(self->camera.updatecfg) {
clock = self->camera.clockMHz;
sprintf(cmd,
"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],
(int)self->camera.xstart, (int)self->camera.ystart,
(int)self->camera.xend, (int)self->camera.yend, self->camera.exposure,
self->camera.temp, (int)self->camera.thresh, (int)self->camera.shopt,
(int)self->camera.shclt
);
len = strlen(cmd);
self->camera.updatecfg = 0;
}
break;
default:
snprintf(logmsg, MSGLEN, "CAM:(camdriv_out) Unhandled event %s", event_names[Eo.ca]);
SICSLogWrite(logmsg, eLogError);
return 0;
return -1;
}
AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN);
if (self->debug) {
@@ -656,16 +627,19 @@ int camdriv_out(void *me, event_t Eo) {
event_names[Eo.ca], event_signatures[Eo.ca]);
SICSLogWrite(logmsg, eLog);
}
return -1;
}
if (Eo.cm) {
snprintf(logmsg, MSGLEN, "TODO:(camdriv_out:Eo.cm): ev=%s, output=%s\n",
event_names[Eo.cm], event_signatures[Eo.cm]);
SICSLogWrite(logmsg, eLogError);
return -1;
}
if (Eo.cd) {
snprintf(logmsg, MSGLEN, "TODO:(camdriv_out:Eo.cm): ev=%s, output=%s\n",
event_names[Eo.cd], event_signatures[Eo.cd]);
SICSLogWrite(logmsg, eLogError);
return -1;
}
if (Eo.dr) {
/* send msg to SICS */
@@ -682,15 +656,28 @@ int camdriv_out(void *me, event_t Eo) {
default:
snprintf(logmsg, MSGLEN, "CAM:(camdriv_out) Unhandled event %s", event_names[Eo.dr]);
SICSLogWrite(logmsg, eLogError);
return 0;
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;
}
return 1;
if (Eo.cl) {
switch (Eo.cl) {
case ECL_RDY:
return ECL_RDY;
break;
default:
snprintf(logmsg, MSGLEN, "CAM:(camdriv_out) Unhandled event %s", event_names[Eo.cl]);
SICSLogWrite(logmsg, eLogError);
return -1;
}
return -1;
}
return -1;
}
static int cb_state_timer(void *ctx, int mode) {
CamObj *self = (CamObj *) ctx;
@@ -727,6 +714,10 @@ static int cb_getstate(pAsyncTxn txn) {
SICSLogWrite(message, eLogError);
ret = 0;
} else {
if (self->debug) {
snprintf(message, MSGLEN, "DEBUG:(cb_getstate) Camera reply: %s", resp);
SICSLogWrite(message, eLog);
}
cm_sym = camera_model(ca_sym);
run_sm(self, cm_sym);
}