/*---------------------------------------------------------------------------
ease.c

basics for (ea)sy implementable (s)ample (e)nvironment devices.
handles background activity and connections over rs232.

Markus Zolliker, March 2005
----------------------------------------------------------------------------
*/

#ifndef EASE_H
#define EASE_H

#include <time.h>
#include "rs232controller.h"
#include "pardef.h"
#include "fsm.h"

#define EASE_ILL_ANS -3000
#define EASE_FAULT -3001
#define EASE_DEV_CHANGED -3002

#define EASE_RUN 0

typedef enum { EASE_offline, EASE_notconnected, EASE_connecting,
  EASE_idle, EASE_abort, EASE_read, EASE_expect, EASE_lost
} EaseState;
typedef enum { EASE_notMonitored, EASE_inTolerance,
      EASE_outOfTolerance } EaseTolState;

typedef struct {
  ParData p;
  FsmHandler handler;
  FsmFunc start;
  FsmFunc idle;
  FsmFunc read;
  FsmFunc doit;
  FsmFunc todo;
  rs232 *ser;
  Fsm *task;                    /* a pointer to the task */
  int errCode;                  /* error code of last operation. not changed on success  */
  EaseState state;
  time_t cmdtime;
  time_t chktime;
  int syntax;                   /* not used in ease, may be used by the driver. used by oxinst.c */
  char cmd[64];
  char ans[64];
  char version[64];
  char msg[256];
  int maxflag;
  time_t readPeriod;
  unsigned long *updateFlags;
  int startOk;
  char *sendCmd;
  int tmo;
} EaseBase;

typedef struct {
  EaseBase b;
  IDrivable *drivInt;
  EVInterface *evInt;
  EVMode eMode;
  int stopped;
  int hwstate;                  /* SICS driver state */
  EaseTolState tolState;
  float upperLimit;
  float lowerLimit;
  float tolerance;
  int maxwait;
  int settle;
  float targetValue;
  time_t timeout, finish;
  int usedSettle;
} EaseDriv;

ParClass *EaseBaseClass(void);
ParClass *EaseDrivClass(void);

EaseBase *EaseBaseCast(void *object);
EaseDriv *EaseDrivCast(void *object);

void EaseWriteError(EaseBase * eab);
void EaseWrite(EaseBase * eab, char *cmd);
int EaseWaitRead(EaseBase * eab);
int EaseHandler(EaseBase * eab);
void EaseBasePar(void *object);
void EaseSendPar(void *object);
void EaseMsgPar(void *object);
void EaseKillDriv(EaseDriv * ead);
void EaseDrivPar(void *object, char *fmt, char *unit);
void EasePchk(void *drv);
void EaseParHasChanged(void);
void EaseStop(EaseBase * eab, char *reason);
int EaseCheckDoit(EaseBase * eab);
int EaseNextFullRead(EaseBase * eab);

int EaseUpdate(int flag);       /* used inside pardef, after ParName and before
                                   the parameter definition. 
                                   The specified flag is updated
                                   when the parameter was changed.
                                   returns 1 when changed, 0 when not changed
                                   calls ParAccess(usUser) and ParSave(1), as
                                   this seems to be useful for parameters
                                   that reflect a state of the device. */
int EaseNextUpdate(void *object);
                          /* get next update flag and clear it.
                             return the next set update flag or -1 when no 
                             flag was set. */
int EaseGetUpdate(void *object, int flag);
                          /* get update flag. return the state of the
                             specified flag */
void EaseSetUpdate(void *object, int flag, int state);
                          /* set an update flag  */

void *EaseMakeBase(SConnection * con, void *class, int argc, char *argv[],
                   int dynamic, int maxflag,
                   ParDef pardef,
                   FsmHandler handler,
                   FsmFunc start, FsmFunc idle, FsmFunc read);
void *EaseMakeDriv(SConnection * con, void *class, int argc, char *argv[],
                   int dynamic, int maxflag,
                   ParDef pardef,
                   FsmHandler handler,
                   FsmFunc start, FsmFunc idle, FsmFunc read, FsmFunc run);

#endif
