/*---------------------------------------------------------------------------
amilevel.c

Driver for the AMI 135/136 level meter

Markus Zolliker, May 2007
----------------------------------------------------------------------------*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/time.h>
#include <math.h>
#include <tcl.h>
#include <fortify.h>
#include <sics.h>
#include <splitter.h>
#include <obpar.h>
#include <devexec.h>
#include <nserver.h>
#include <interrupt.h>
#include <emon.h>
#include <evcontroller.h>
#include <evcontroller.i>
#include <servlog.h>
#include <sicsvar.h>
#include <evdriver.i>
#include <rs232controller.h>
#include "lscsupport.h"
#include "fsm.h"
#include "initializer.h"

#define PID_FLAG 1
#define RDGRNG_FLAG 2
#define HTRRNG_FLAG 3

typedef struct {
  EaseBase b;
  float level;
} Ami;

static ParClass amiClass = { "AMILEVEL", sizeof(Ami) };

/*----------------------------------------------------------------------------*/
static void AmiParDef(void *object)
{
  Ami *drv = ParCast(&amiClass, object);
  EaseBase *eab = object;

  ParName("");
  ParTail("cm");
  ParFloat(&drv->level, PAR_NAN);

  EaseBasePar(drv);
  EaseSendPar(drv);
  ParStdDef();
  EaseMsgPar(drv);
}

/*----------------------------------------------------------------------------*/
static long AmiRead(long pc, void *object)
{
  Ami *drv = ParCast(&amiClass, object);
  EaseBase *eab = object;

  switch (pc) {
  default:                     /* FSM BEGIN ****************************** */
    EasePchk(drv);
    EaseWrite(eab, "level");
    return __LINE__;
  case __LINE__:                 /**********************************/
    drv->level = atof(eab->ans);
    ParLog(drv);
  fsm_quit:return 0;
  }                             /* FSM END ******************************** */
}

/*----------------------------------------------------------------------------*/
static long AmiStart(long pc, void *object)
{
  Ami *drv = ParCast(&amiClass, object);
  EaseBase *eab = object;

  switch (pc) {
  default:                     /* FSM BEGIN ****************************** */
    EasePchk(drv);
    EaseWrite(eab, "cm");
    return __LINE__;
  case __LINE__:                 /**********************************/

  quit:
    return 0;
  }                             /* FSM END ******************************************* */
}

/*----------------------------------------------------------------------------*/
static int AmiInit(SConnection * con, int argc, char *argv[], int dynamic)
{
  /* args:
     MakeObject objectname ami <rs232>
     MakeObject objectname ami <host> <port>
   */
  Ami *drv;

  drv = EaseMakeBase(con, &amiClass, argc, argv, dynamic, 7,
                     AmiParDef, LscHandler, AmiStart, NULL, AmiRead);
  if (drv == NULL)
    return 0;
  setRS232ReplyTerminator(drv->b.ser, "\n");
  setRS232SendTerminator(drv->b.ser, "\n");
  return 1;
}

/*----------------------------------------------------------------------------*/
void AmiStartup(void)
{
  ParMakeClass(&amiClass, EaseBaseClass());
  MakeDriver("AMILEVEL", AmiInit, 0, "Ami 135/136 level meter");
}
