Files
sics/site_ansto/hardsup/camera.h
Ferdi Franceschini ad27488d3d Initial implementation of Dingo Camera driver.
Takes a single shot or a multishot.
If the user changes the camera configuration in SICS the new config will
be uploaded when the next take shot/multishot command is sent.
This driver allows the scan object in SICS to drive the scan variable to
the next target while the camera is processing and saving data after
acquiring an image.
TODO
Implement "set file,..." command.
2013-02-26 01:20:02 +11:00

248 lines
8.0 KiB
C

/**
* \file camera.h
* \brief Enumerates event codes and states, and defines the abstract
* types used in the state machine.
*
* \Author Ferdi Franceschini February 2013
*
* Copyright: see file Copyright.txt
*
* 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.
*
* 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
* 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.
* 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,
* EDR:Driver events.
*
* 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
* trans fn: QXEin -> Q
* out fn : QXEin -> Eo
*
* In the implementation the transition and output functions are combined in
* TRANS_TABLE.
*/
#ifndef CAMERA_H
#define CAMERA_H
/* END_TABLE marks the last row in the transition table */
#define END_TABLE -1
/* EVENT CODES */
/* All event enum constants start with 'EXX_', XX identifies the source
* ECA_ : Camera event stream. Messages destined for or received from the camera.
* ECM_ : Events from the camera model.
* ECD_ : Command input, either directly from a user or via the scan command
* EDR_ : Driver events
*/
#define CAMERA_CMDS_TABLE \
TR(ECA_SET_CAM, "set camera") \
TR(ECA_TK_SHOT, "take shot") \
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")
#define CAMERA_MSGS_TABLE \
TR(ECA_START, "StartTime") \
TR(ECA_OK, "OK") \
TR(ECA_FAIL, "Fail") \
TR(ECA_IDLE, "Idle") \
TR(ECA_OPEN_SHUTR, "Open") \
TR(ECA_CLOSE_SHUTR, "Close") \
TR(ECA_ACQ_IMAGE, "Acq") \
TR(ECA_READ_IMAGE, "Read") \
TR(ECA_SEND_IMAGE, "Send") \
TE(ECA_STOP, "Stop")
#define CAM_MOD_EVENT_TABLE \
TR(ECM_UNKNOWN, "Stop message received from camera") \
TR(ECM_STOP, "Stop message received from camera") \
TR(ECM_IDLE, "Camera in idle state") \
TR(ECM_FAIL, "Command rejected") \
TR(ECM_ACQ, "catch-all for start of acq phase") \
TE(ECM_PROC, "catch-all for end of acq phase")
/* COMMAND EVENTS
* These are events triggered by user input.
* The events can be direct via the 'send' subcommand or
* indirect via the scan command through the counter interface.
*/
#define CMD_EVENT_TABLE \
TR(ECD_CLEAR, "Clear latched command") \
TR(ECD_TK_SHOT, "take shot") \
TR(ECD_MLTI_ON, "take multi on") \
TR(ECD_MLTI_OFF, "take multi off") \
TR(ECD_GET_STATE, "get state") \
TE(ECD_GET_STATUS, "get status")
/* DRIVER EVENT TABLE
* These events are of interest to SICS.
*/
#define DRIVER_EVENT_TABLE \
TR(EDR_IDLE, "HWIDLE") \
TR(EDR_BUSY, "HWBUSY") \
TE(EDR_FAULT, "HWFAULT")
#define ESLEN 32
/* STATE CODES
* SXX_ State code enum constants, XX identifies a component of the system.
* SCL_ Command latch states
* SCM_ Camera model states
* SDR_ Driver states
*/
#define COMMAND_LATCH_STATE_TABLE \
TR(SCL_RDY, "command latch ready to accept") \
TR(SCL_TK_SHOT, "latched a take shot command") \
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")
#define CAMERA_MODEL_STATE_TABLE \
TR(SCM_IDLE, "Camera is idle") \
TR(SCM_ACQ, "Camera is acquiring an image") \
TE(SCM_PROC, "Camera is processing an image")
#define DRIVER_STATE_TABLE \
TR(SDR_IDLE, "HWIdle") \
TR(SDR_BUSY, "HWBusy") \
TE(SDR_FAULT, "HWFault")
#define SSLEN 32
/* 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};
#undef TR
#undef TE
#define TR(n,d) n,
#define TE(n,d) n
enum command_latch_states {CL_Z,COMMAND_LATCH_STATE_TABLE};
enum camera_model_states {CM_Z,CAMERA_MODEL_STATE_TABLE};
enum driver_states {DR_Z,DRIVER_STATE_TABLE};
#undef TR
#undef TE
extern char *SCL_NAMES[];
extern char *SCM_NAMES[];
extern char *SDR_NAMES[];
/* List of names generated from the event_codes. */
extern char *event_names[];
/* The signature array includes the identifying characters at the start of a reply.
* as well as camera commands or just describes the corresponding symbols.
*/
extern char *event_signatures[];
/* Output event channel
* A tuple (Eca,Ecm,Ecd,Edr) in ECA X ECM X ECD X EDR
*/
typedef struct {
enum event_codes ca;
enum event_codes cm;
enum event_codes cd;
enum event_codes dr;
} event_t;
/* A tuple (Scl,Scm,Sdr) in SCL X SCM X SDR */
typedef struct {
int cl;
int cm;
int dr;
} state_t;
/* Defines a row in the transition table */
typedef struct {
state_t Sc;
enum event_codes Ei;
event_t Eo;
state_t Sn;
} trans_t;
/* Transfer object for state machine IO and transitions
* output_fn: This is the output function callback. It must be defined by the
* IO layer (ie cameradriver.c).
*/
typedef struct {
state_t Sc;
event_t Eo;
int multi;
int debug;
int (*output_fn)(void *caller, event_t Eo);
} camsm_t;
/* Are we in the SCL_XX, SCM_ or SDR_ state?
* NOTE: 0 is a wildcard so any Sc.cl value matches St.cl==0
*/
#define INCL(Sc,St) (!St.cl || Sc.cl==St.cl)
#define INCM(Sc,St) (!St.cm || Sc.cm==St.cm)
#define INDR(Sc,St) (!St.dr || Sc.dr==St.dr)
/* INSYS is True if system state Sc is in St.
* St is normally the current state in the transition table
* and describes a range of possible states.
*/
#define INSYS(Sc,St) ( INCL(Sc,St) && INCM(Sc,St) && INDR(Sc,St) )
/* Clear the given event */
void EVclr(event_t *E);
/* Set E to Ev */
void EVset(event_t *E, event_t Ev);
/* Set Sc to St */
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 */
enum event_codes camera_model(enum event_codes event);
/* \brief Determines camera state from camera status message and reads acquisition
* time if camera is running.
* \param msg camera status message from the "get status" command.
* \param ca_sym symbol for the camera state in the status message, one of ECA_ enums.
* \param time_rem time remaining during while the camera is running.
* \param time_tot total time while the camera is running.
*/
int cam_parse_status(char *msg, enum event_codes *ca_sym, int *time_rem, int *time_tot);
/* \brief Transition function for the camera system state machine.
* \param Sc the current system state.
* \param Ein input event.
* \param Sn the next system state.
* \param Eo the output events.
*/
int cam_trans_fn(state_t Sc, enum event_codes Ein, state_t *Sn, event_t *Eo);
/* \brief This is the state machine input function called by the IO layer (ie cameradriver.c)
*
* \param caller, Provides context info for the ouput function callback.
* \param self, Provides current state on input and next state and output event on return.
*/
void camdriv_input(void *caller, camsm_t *self, enum event_codes event_sym);
/* Convenience functions to convert a state or event to a descriptive string */
char *strstate(state_t s);
char *strevent(event_t E);
/* The transition table */
extern trans_t TRANS_TABLE[];
#endif