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:
@ -19,12 +19,13 @@ void print_state(state_t s) {
|
||||
}
|
||||
|
||||
void print_event(event_t E) {
|
||||
char *ca, *cm, *cd, *dr;
|
||||
char *ca, *cm, *cd, *dr, *cl;
|
||||
ca = event_names[E.ca];
|
||||
cm = event_names[E.cm];
|
||||
cd = event_names[E.cd];
|
||||
dr = event_names[E.dr];
|
||||
printf("%s,%s,%s,%s", ca, cm, cd, dr);
|
||||
cl = event_names[E.cl];
|
||||
printf("%s,%s,%s,%s,%s", ca, cm, cd, dr, cl);
|
||||
}
|
||||
|
||||
event_t output(state_t Sc, enum event_codes Ei) {
|
||||
@ -78,7 +79,7 @@ int test_camrep2sym(void) {
|
||||
|
||||
int test_trans_fn(void) {
|
||||
int i;
|
||||
event_t Eo={0,0,0,0};
|
||||
event_t Eo={0,0,0,0,0};
|
||||
|
||||
|
||||
state_t Sc = {.cl=SCL_RDY, .cm=SCM_IDLE, .dr=SDR_IDLE};
|
||||
@ -101,6 +102,15 @@ int test_trans_fn(void) {
|
||||
printf(",\t");
|
||||
print_event(Eo);
|
||||
printf("\n");
|
||||
if (Eo.cl) {
|
||||
/* TODO Handle feedback in the general case where there may be multiple events in Eo to feed back into the transition function */
|
||||
printf("%s,\t",event_names[Eo.cl]);
|
||||
print_state(Sc);
|
||||
cam_trans_fn(Sc, Eo.cl, &Sc, &Eo);
|
||||
printf(",\t");
|
||||
print_event(Eo);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "TEST_TRANS_FN:OUTPUT:END\n");
|
||||
return 1;
|
||||
@ -120,7 +130,10 @@ int camdriv_out(void *me, event_t Eo) {
|
||||
if (Eo.dr) {
|
||||
printf("camdriv_out: symbol=%s, output=%s\n", event_names[Eo.dr], event_signatures[Eo.dr]);
|
||||
}
|
||||
return 1;
|
||||
if (Eo.cl) {
|
||||
printf("camdriv_out: symbol=%s, output=%s\n", event_names[Eo.cl], event_signatures[Eo.cl]);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int test_camdriv_event_io(void) {
|
||||
@ -139,12 +152,14 @@ int test_camdriv_event_io(void) {
|
||||
|
||||
printf("input: %s :", event_names[Ein]);
|
||||
print_state(cdinfo.Sc);
|
||||
printf("\n");
|
||||
camdriv_input(&self, &cdinfo, Ein);
|
||||
|
||||
Ein = ECM_IDLE;
|
||||
printf("input: %s :", event_names[Ein]);
|
||||
cdinfo.Sc.cl=SCL_TK_SHOT;
|
||||
print_state(cdinfo.Sc);
|
||||
printf("\n");
|
||||
camdriv_input(&self, &cdinfo, Ein);
|
||||
|
||||
fprintf(stderr, "TEST_CAMDRIVER_EVENT_IO:OUPUT:END\n");
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#define TR(a,b) #a,
|
||||
#define TE(a,b) #a
|
||||
char *event_names[] = { "0", CAMERA_CMDS_TABLE, CAMERA_MSGS_TABLE, CAM_MOD_EVENT_TABLE, DRIVER_EVENT_TABLE, CMD_EVENT_TABLE };
|
||||
char *event_names[] = { "0", CAMERA_CMDS_TABLE, CAMERA_MSGS_TABLE, CAM_MOD_EVENT_TABLE, DRIVER_EVENT_TABLE, CMD_EVENT_TABLE, CMD_LATCH_EVENT_TABLE};
|
||||
#undef TR
|
||||
#undef TE
|
||||
|
||||
@ -47,6 +47,7 @@ void EVclr(event_t *E) {
|
||||
E->cm=0;
|
||||
E->cd=0;
|
||||
E->dr=0;
|
||||
E->cl=0;
|
||||
}
|
||||
|
||||
/* Set event channel */
|
||||
@ -55,6 +56,7 @@ void EVset(event_t *E, event_t Ev) {
|
||||
if (Ev.cm) E->cm = Ev.cm;
|
||||
if (Ev.cd) E->cd = Ev.cd;
|
||||
if (Ev.dr) E->dr = Ev.dr;
|
||||
if (Ev.cl) E->cl = Ev.cl;
|
||||
}
|
||||
|
||||
/* Set system state */
|
||||
@ -121,7 +123,14 @@ enum event_codes cam_rep2sym(char *msg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* return 0 = no transition,
|
||||
/* \brief Transition function. Given an input event it maps the current state
|
||||
* to the next state and output.
|
||||
*
|
||||
* \param Sc current state.
|
||||
* \param Ein input event.
|
||||
* \param Sn will be set to the next state.
|
||||
* \param Eo will be set as the output event.
|
||||
* return 0 = no transition,
|
||||
* return 1 = transition
|
||||
*/
|
||||
int cam_trans_fn(state_t Sc, enum event_codes Ein, state_t *Sn, event_t *Eo) {
|
||||
@ -141,11 +150,23 @@ int cam_trans_fn(state_t Sc, enum event_codes Ein, state_t *Sn, event_t *Eo) {
|
||||
}
|
||||
|
||||
/* TODO Do we need Eo in self, should camsm_t be refactored to remove it? */
|
||||
/* \brief Takes an input event from the camera driver, runs it through the
|
||||
* state machine and sets the current state equal to the next state.
|
||||
*
|
||||
* \param caller is a reference to the object (ie camera driver) sending the event.
|
||||
* \param self is a reference to the state machine transfer object.
|
||||
* \param event_sym is the input event symbol.
|
||||
*/
|
||||
void camdriv_input(void *caller, camsm_t *self, enum event_codes event_sym) {
|
||||
int input_event;
|
||||
state_t Sn;
|
||||
cam_trans_fn(self->Sc, event_sym, &Sn, &self->Eo);
|
||||
self->output_fn(caller, self->Eo);
|
||||
self->Sc = Sn;
|
||||
|
||||
input_event = event_sym;
|
||||
while (input_event != -1) {
|
||||
cam_trans_fn(self->Sc, input_event, &Sn, &self->Eo);
|
||||
input_event = self->output_fn(caller, self->Eo);
|
||||
self->Sc = Sn;
|
||||
}
|
||||
}
|
||||
|
||||
char *strstate(state_t s) {
|
||||
@ -158,12 +179,13 @@ char *strstate(state_t s) {
|
||||
}
|
||||
|
||||
char *strevent(event_t E) {
|
||||
char *ca, *cm, *cd, *dr;
|
||||
char *ca, *cm, *cd, *dr, *cl;
|
||||
ca = event_names[E.ca];
|
||||
cm = event_names[E.cm];
|
||||
cd = event_names[E.cd];
|
||||
dr = event_names[E.dr];
|
||||
snprintf(event_str, ESLEN, "%s,%s,%s,%s", ca, cm, cd, dr);
|
||||
cl = event_names[E.cl];
|
||||
snprintf(event_str, ESLEN, "%s,%s,%s,%s,%s", ca, cm, cd, dr, cl);
|
||||
return event_str;
|
||||
}
|
||||
|
||||
@ -190,16 +212,18 @@ char *strevent(event_t E) {
|
||||
* 0 = no change for components of next state.
|
||||
*/
|
||||
trans_t TRANS_TABLE[] = {
|
||||
{{.cl=SCL_RDY, .dr=SDR_IDLE}, ECD_TK_SHOT, {.dr=0}, {.cl=SCL_TK_SHOT}},
|
||||
{{.cl=SCL_RDY, .dr=SDR_IDLE}, ECD_MLTI_ON, {.dr=0}, {.cl=SCL_TK_MLTI}},
|
||||
{{.cl=SCL_RDY}, ECD_TK_SHOT, {.dr=0}, {.cl=SCL_CFG_TK_SHOT}},
|
||||
{{.cl=SCL_RDY}, ECD_MLTI_ON, {.dr=0}, {.cl=SCL_CFG_TK_MLTI}},
|
||||
{{.cl=SCL_CFG_TK_SHOT}, ECM_IDLE, {.ca=ECA_CFG}, {.cl=SCL_TK_SHOT}},
|
||||
{{.cl=SCL_TK_SHOT}, ECM_IDLE, {.ca=ECA_TK_SHOT}, {.cl=SCL_WT}},
|
||||
{{.cl=SCL_TK_MLTI}, ECD_MLTI_OFF,{.dr=0}, {.cl=SCL_RDY}},
|
||||
{{.cl=SCL_CFG_TK_MLTI}, ECD_MLTI_OFF,{.cl=ECL_RDY}, {.cl=SCL_RDY}},
|
||||
{{.cl=SCL_TK_MLTI}, ECD_MLTI_OFF,{.cl=ECL_RDY}, {.cl=SCL_RDY}},
|
||||
{{.cl=SCL_CFG_TK_MLTI}, ECM_IDLE, {.ca=ECA_CFG}, {.cl=SCL_TK_MLTI}},
|
||||
{{.cl=SCL_TK_MLTI}, ECM_IDLE, {.ca=ECA_MLTI_ON}, {.cl=SCL_MLTI_ON}},
|
||||
{{.cl=SCL_MLTI_ON}, ECD_MLTI_OFF,{.ca=ECA_MLTI_OFF},{.cl=SCL_WT}},
|
||||
{{.cl=SCL_WT}, ECM_ACQ, {.dr=0}, {.cl=SCL_RDY}},
|
||||
{{.cl=SCL_WT}, ECM_PROC, {.dr=0}, {.cl=SCL_RDY}},
|
||||
{{.cl=SCL_WT}, ECM_STOP, {.dr=0}, {.cl=SCL_RDY}},
|
||||
{{.cl=SCL_WT}, ECM_IDLE, {.dr=0}, {.cl=SCL_RDY}},
|
||||
{{.cl=SCL_WT}, ECM_PROC, {.cl=ECL_RDY}, {.cl=SCL_RDY}},
|
||||
{{.cl=SCL_WT}, ECM_STOP, {.cl=ECL_RDY}, {.cl=SCL_RDY}},
|
||||
{{.cl=SCL_WT}, ECM_IDLE, {.cl=ECL_RDY}, {.cl=SCL_RDY}},
|
||||
|
||||
{{.cm=SCM_IDLE}, ECM_ACQ, {.dr=0}, {.cm=SCM_ACQ}},
|
||||
{{.cm=SCM_IDLE}, ECM_PROC, {.dr=0}, {.cm=SCM_PROC}},
|
||||
@ -211,8 +235,6 @@ trans_t TRANS_TABLE[] = {
|
||||
|
||||
{{.dr=SDR_IDLE}, ECD_TK_SHOT, {.dr=EDR_BUSY}, {.dr=SDR_BUSY}},
|
||||
{{.dr=SDR_IDLE}, ECD_MLTI_ON, {.dr=EDR_BUSY}, {.dr=SDR_BUSY}},
|
||||
{{.dr=SDR_BUSY, .cl=SCL_RDY}, ECM_PROC, {.dr=EDR_IDLE}, {.dr=SDR_IDLE}},
|
||||
{{.dr=SDR_BUSY, .cl=SCL_RDY}, ECM_STOP, {.dr=EDR_IDLE}, {.dr=SDR_IDLE}},
|
||||
{{.dr=SDR_BUSY, .cl=SCL_RDY}, ECM_IDLE, {.dr=EDR_IDLE}, {.dr=SDR_IDLE}},
|
||||
{{.dr=SDR_BUSY}, ECL_RDY, {.dr=EDR_IDLE}, {.dr=SDR_IDLE}},
|
||||
{{.dr=END_TABLE}, END_TABLE, {.dr=END_TABLE}, {.dr=END_TABLE}}
|
||||
};
|
||||
|
@ -9,15 +9,15 @@
|
||||
*
|
||||
* Deterministic Finite State machine transducer (Mealy)
|
||||
* The idea is to synthesize a state machine which handles the union of input
|
||||
* events for a given set state machines in a system.
|
||||
* events for a given set of state machines in a system.
|
||||
*
|
||||
* The system is made up of three components, a command latch (CL), a camera
|
||||
* model (CM) and the driver (DR). The system state machine is considered to be
|
||||
* model (CM) and the driver (DR). The system's state machine is considered to be
|
||||
* made up of the component state machines running in parallel and with some of
|
||||
* the component state machine transitions being restricted by system state
|
||||
* transition rules.
|
||||
* The sets of states are,
|
||||
* SCL:Command Latch states, SCM:Camera Model states, SCDR:Driver states.
|
||||
* SCL:Command Latch states, SCM:Camera Model states, SDR:Driver states.
|
||||
* Q is the set of system states.
|
||||
* The sets of event symbols are defined as,
|
||||
* ECA:Camera events, ECM:Camera model events, ECD:User command events,
|
||||
@ -25,11 +25,20 @@
|
||||
*
|
||||
* The system state machine for the camera driver is defined as follows.
|
||||
* In the following, '<' means subset
|
||||
* Q < SCL X SCM X SCDR
|
||||
* Ein = ECA U ECM U ECD U EDR
|
||||
* Eo < ECA X ECM X ECD X EDR
|
||||
* Q < SCL X SCM X SDR
|
||||
* Ein = ECA U ECM U ECD U EDR U ECL
|
||||
* Eo < ECA X ECM X ECD X EDR X ECL
|
||||
* trans fn: QXEin -> Q
|
||||
* out fn : QXEin -> Eo
|
||||
* out fn: QXEin -> Eo
|
||||
*
|
||||
* Command Latch State Machine (the SCL_XXX states):
|
||||
* Waits for camera to be idle before sending a command and emits a ECL_RDY
|
||||
* event when it is ready to accept a new command.
|
||||
* Camera Model State Machine (the SCM_XXX states):
|
||||
* Reduces the number of camera states by grouping them into categories of
|
||||
* interest to the driver.
|
||||
* Driver State Machine (the SDR_XXX states):
|
||||
* Reports HWIdle, HWBusy, HWFault states to SICS.
|
||||
*
|
||||
* In the implementation the transition and output functions are combined in
|
||||
* TRANS_TABLE.
|
||||
@ -52,7 +61,8 @@
|
||||
TR(ECA_MLTI_ON, "take multi on") \
|
||||
TR(ECA_MLTI_OFF, "take multi off") \
|
||||
TR(ECA_GET_STATUS, "get status") \
|
||||
TE(ECA_GET_STATE, "get state")
|
||||
TR(ECA_GET_STATE, "get state") \
|
||||
TE(ECA_CFG, "send configuration")
|
||||
|
||||
#define CAMERA_MSGS_TABLE \
|
||||
TR(ECA_START, "StartTime") \
|
||||
@ -95,7 +105,14 @@
|
||||
TR(EDR_BUSY, "HWBUSY") \
|
||||
TE(EDR_FAULT, "HWFAULT")
|
||||
|
||||
#define ESLEN 32
|
||||
/* COMMAND LATCH EVENT TABLE
|
||||
* These events are of interest to the SDR driver state machine.
|
||||
*/
|
||||
#define CMD_LATCH_EVENT_TABLE \
|
||||
TE(ECL_RDY, "Latch ready to accept a command")
|
||||
|
||||
/* Event message/description string length excluding \0 */
|
||||
#define ESLEN 64
|
||||
|
||||
/* STATE CODES
|
||||
* SXX_ State code enum constants, XX identifies a component of the system.
|
||||
@ -105,7 +122,9 @@
|
||||
*/
|
||||
#define COMMAND_LATCH_STATE_TABLE \
|
||||
TR(SCL_RDY, "command latch ready to accept") \
|
||||
TR(SCL_CFG_TK_SHOT, "take shot waiting to send config") \
|
||||
TR(SCL_TK_SHOT, "latched a take shot command") \
|
||||
TR(SCL_CFG_TK_MLTI, "multi-shot waiting to send config") \
|
||||
TR(SCL_TK_MLTI, "latched a multi-shot command") \
|
||||
TR(SCL_MLTI_ON, "multi-shot is running") \
|
||||
TE(SCL_WT, "waiting for camera to start acquisition")
|
||||
@ -125,7 +144,7 @@
|
||||
/* Enumerate event and state symbols */
|
||||
#define TR(a,b) a,
|
||||
#define TE(a,b) a
|
||||
enum event_codes {ECA_UNKNOWN, CAMERA_CMDS_TABLE, CAMERA_MSGS_TABLE, CAM_MOD_EVENT_TABLE, DRIVER_EVENT_TABLE, CMD_EVENT_TABLE};
|
||||
enum event_codes {ECA_UNKNOWN, CAMERA_CMDS_TABLE, CAMERA_MSGS_TABLE, CAM_MOD_EVENT_TABLE, DRIVER_EVENT_TABLE, CMD_EVENT_TABLE, CMD_LATCH_EVENT_TABLE};
|
||||
#undef TR
|
||||
#undef TE
|
||||
|
||||
@ -152,13 +171,14 @@ extern char *event_signatures[];
|
||||
|
||||
|
||||
/* Output event channel
|
||||
* A tuple (Eca,Ecm,Ecd,Edr) in ECA X ECM X ECD X EDR
|
||||
* A tuple (Eca,Ecm,Ecd,Edr,Ecl) in ECA X ECM X ECD X EDR X ECL
|
||||
*/
|
||||
typedef struct {
|
||||
enum event_codes ca;
|
||||
enum event_codes cm;
|
||||
enum event_codes cd;
|
||||
enum event_codes dr;
|
||||
enum event_codes cl;
|
||||
} event_t;
|
||||
|
||||
/* A tuple (Scl,Scm,Sdr) in SCL X SCM X SDR */
|
||||
@ -211,7 +231,7 @@ void STset(state_t *Sc, state_t St);
|
||||
/* \brief Translates a camera status message to a camera (ECA_) event */
|
||||
enum event_codes cam_rep2sym(char *msg);
|
||||
|
||||
/* \brief Converts a camera (ECA_) event to a camera modle (ECM_) event */
|
||||
/* \brief Converts a camera (ECA_) event to a camera model (ECM_) event */
|
||||
enum event_codes camera_model(enum event_codes event);
|
||||
|
||||
/* \brief Determines camera state from camera status message and reads acquisition
|
||||
|
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user