/** * \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 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'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, 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, * 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 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 * * 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. */ #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") \ TR(ECA_GET_STATE, "get state") \ TE(ECA_CFG, "update camera settings, file configuration and meta data") #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") /* 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. * 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_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") #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, CMD_LATCH_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,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 */ 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 model (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