Stage 1 reorganization
Directory moves. src/RTEMS/ => src/libCom/RTEMS/ src/as/ => src/ioc/as/ src/bpt/ => src/ioc/bpt/ src/ca/ => src/ca/client/ src/cap5/ => src/ca/client/perl/ src/cas/ => src/ca/legacy/pcas/ src/catools/ => src/ca/client/tools/ src/db/ => src/ioc/db/ src/dbStatic/ => src/ioc/dbStatic/ src/dbtools/ => src/ioc/dbtemplate/ src/dev/softDev/ => src/std/dev/ src/dev/testDev/ => src/std/test/ src/excas/ => src/ca/legacy/pcas/ex/ src/gdd/ => src/ca/legacy/gdd/ src/makeBaseApp/ => src/template/base/ src/makeBaseExt/ => src/template/ext/ src/misc/ => src/ioc/misc/ src/rec/ => src/std/rec/ src/registry/ => src/ioc/registry/ src/rsrv/ => src/ioc/rsrv/ src/softIoc/ => src/std/softIoc/ src/toolsComm/ => src/libCom/tools/
This commit is contained in:
committed by
Andrew Johnson
parent
4a18db9f99
commit
2a36a3906d
298
src/std/dev/devGeneralTime.c
Normal file
298
src/std/dev/devGeneralTime.c
Normal file
@@ -0,0 +1,298 @@
|
||||
/*************************************************************************\
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* $Revision-Id$ */
|
||||
/*
|
||||
* Original Author: Sheng Peng, ORNL / SNS Project
|
||||
* Date: 07/2004
|
||||
*
|
||||
* EPICS device support for general timestamp support
|
||||
*
|
||||
* Integrated into base by Peter Denison, Diamond Light Source
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "alarm.h"
|
||||
#include "dbDefs.h"
|
||||
#include "dbAccess.h"
|
||||
#include "recGbl.h"
|
||||
#include "devSup.h"
|
||||
#include "epicsString.h"
|
||||
#include "epicsGeneralTime.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
#include "aiRecord.h"
|
||||
#include "boRecord.h"
|
||||
#include "longinRecord.h"
|
||||
#include "stringinRecord.h"
|
||||
|
||||
|
||||
/********* ai record **********/
|
||||
static int getCurrentTime(double * pseconds)
|
||||
{
|
||||
epicsTimeStamp ts;
|
||||
|
||||
if (epicsTimeERROR != epicsTimeGetCurrent(&ts)) {
|
||||
*pseconds = ts.secPastEpoch + ((double)(ts.nsec)) * 1e-9;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct ai_channel {
|
||||
char *name;
|
||||
int (*get)(double *);
|
||||
} ai_channels[] = {
|
||||
{"TIME", getCurrentTime},
|
||||
};
|
||||
|
||||
static long init_ai(aiRecord *prec)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (prec->inp.type != INST_IO) {
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devAiGeneralTime::init_ai: Illegal INP field");
|
||||
prec->pact = TRUE;
|
||||
return S_db_badField;
|
||||
}
|
||||
|
||||
for (i = 0; i < NELEMENTS(ai_channels); i++) {
|
||||
struct ai_channel *pchan = &ai_channels[i];
|
||||
if (!epicsStrCaseCmp(prec->inp.value.instio.string, pchan->name)) {
|
||||
prec->dpvt = pchan;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devAiGeneralTime::init_ai: Bad parm");
|
||||
prec->pact = TRUE;
|
||||
prec->dpvt = NULL;
|
||||
return S_db_badField;
|
||||
}
|
||||
|
||||
static long read_ai(aiRecord *prec)
|
||||
{
|
||||
struct ai_channel *pchan = (struct ai_channel *)prec->dpvt;
|
||||
|
||||
if (!pchan) return -1;
|
||||
|
||||
if (pchan->get(&prec->val) == 0) {
|
||||
prec->udf = FALSE;
|
||||
return 2;
|
||||
}
|
||||
prec->udf = TRUE;
|
||||
recGblSetSevr(prec, READ_ALARM, INVALID_ALARM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_write;
|
||||
DEVSUPFUN special_linconv;
|
||||
} devAiGeneralTime = {
|
||||
{6, NULL, NULL, init_ai, NULL}, read_ai, NULL
|
||||
};
|
||||
epicsExportAddress(dset, devAiGeneralTime);
|
||||
|
||||
|
||||
/********* bo record **********/
|
||||
static void resetErrors(void)
|
||||
{
|
||||
generalTimeResetErrorCounts();
|
||||
}
|
||||
|
||||
static struct bo_channel {
|
||||
char *name;
|
||||
void (*put)(void);
|
||||
} bo_channels[] = {
|
||||
{"RSTERRCNT", resetErrors},
|
||||
};
|
||||
|
||||
static long init_bo(boRecord *prec)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (prec->out.type != INST_IO) {
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devAiGeneralTime::init_ai: Illegal INP field");
|
||||
prec->pact = TRUE;
|
||||
return S_db_badField;
|
||||
}
|
||||
|
||||
for (i = 0; i < NELEMENTS(bo_channels); i++) {
|
||||
struct bo_channel *pchan = &bo_channels[i];
|
||||
if (!epicsStrCaseCmp(prec->out.value.instio.string, pchan->name)) {
|
||||
prec->dpvt = pchan;
|
||||
prec->mask = 0;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devBoGeneralTime::init_bo: Bad parm");
|
||||
prec->pact = TRUE;
|
||||
prec->dpvt = NULL;
|
||||
return S_db_badField;
|
||||
}
|
||||
|
||||
static long write_bo(boRecord *prec)
|
||||
{
|
||||
struct bo_channel *pchan = (struct bo_channel *)prec->dpvt;
|
||||
|
||||
if (!pchan) return -1;
|
||||
|
||||
pchan->put();
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_write;
|
||||
} devBoGeneralTime = {
|
||||
{5, NULL, NULL, init_bo, NULL}, write_bo
|
||||
};
|
||||
epicsExportAddress(dset, devBoGeneralTime);
|
||||
|
||||
|
||||
/******* longin record *************/
|
||||
static int errorCount(void)
|
||||
{
|
||||
return generalTimeGetErrorCounts();
|
||||
}
|
||||
|
||||
static struct li_channel {
|
||||
char *name;
|
||||
int (*get)(void);
|
||||
} li_channels[] = {
|
||||
{"GETERRCNT", errorCount},
|
||||
};
|
||||
|
||||
static long init_li(longinRecord *prec)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (prec->inp.type != INST_IO) {
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devLiGeneralTime::init_li: Illegal INP field");
|
||||
prec->pact = TRUE;
|
||||
return S_db_badField;
|
||||
}
|
||||
|
||||
for (i = 0; i < NELEMENTS(li_channels); i++) {
|
||||
struct li_channel *pchan = &li_channels[i];
|
||||
if (!epicsStrCaseCmp(prec->inp.value.instio.string, pchan->name)) {
|
||||
prec->dpvt = pchan;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devLiGeneralTime::init_li: Bad parm");
|
||||
prec->pact = TRUE;
|
||||
prec->dpvt = NULL;
|
||||
return S_db_badField;
|
||||
}
|
||||
|
||||
static long read_li(longinRecord *prec)
|
||||
{
|
||||
struct li_channel *pchan = (struct li_channel *)prec->dpvt;
|
||||
|
||||
if (!pchan) return -1;
|
||||
|
||||
prec->val = pchan->get();
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_write;
|
||||
} devLiGeneralTime = {
|
||||
{5, NULL, NULL, init_li, NULL}, read_li
|
||||
};
|
||||
epicsExportAddress(dset, devLiGeneralTime);
|
||||
|
||||
|
||||
/********** stringin record **********/
|
||||
static const char * timeProvider(void)
|
||||
{
|
||||
return generalTimeCurrentProviderName();
|
||||
}
|
||||
|
||||
static const char * highestProvider(void)
|
||||
{
|
||||
return generalTimeHighestCurrentName();
|
||||
}
|
||||
|
||||
static const char * eventProvider(void)
|
||||
{
|
||||
return generalTimeEventProviderName();
|
||||
}
|
||||
|
||||
static struct si_channel {
|
||||
char *name;
|
||||
const char * (*get)(void);
|
||||
} si_channels[] = {
|
||||
{"BESTTCP", timeProvider},
|
||||
{"TOPTCP", highestProvider},
|
||||
{"BESTTEP", eventProvider},
|
||||
};
|
||||
|
||||
static long init_si(stringinRecord *prec)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (prec->inp.type != INST_IO) {
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devSiGeneralTime::init_si: Illegal INP field");
|
||||
prec->pact = TRUE;
|
||||
return S_db_badField;
|
||||
}
|
||||
|
||||
for (i = 0; i < NELEMENTS(si_channels); i++) {
|
||||
struct si_channel *pchan = &si_channels[i];
|
||||
if (!epicsStrCaseCmp(prec->inp.value.instio.string, pchan->name)) {
|
||||
prec->dpvt = pchan;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devSiGeneralTime::init_si: Bad parm");
|
||||
prec->pact = TRUE;
|
||||
prec->dpvt = NULL;
|
||||
return S_db_badField;
|
||||
}
|
||||
|
||||
static long read_si(stringinRecord *prec)
|
||||
{
|
||||
struct si_channel *pchan = (struct si_channel *)prec->dpvt;
|
||||
const char *name;
|
||||
|
||||
if (!pchan) return -1;
|
||||
|
||||
name = pchan->get();
|
||||
if (name) {
|
||||
strncpy(prec->val, name, sizeof(prec->val));
|
||||
prec->val[sizeof(prec->val) - 1] = '\0';
|
||||
} else {
|
||||
strcpy(prec->val, "No working providers");
|
||||
recGblSetSevr(prec, READ_ALARM, MAJOR_ALARM);
|
||||
}
|
||||
prec->udf = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_write;
|
||||
} devSiGeneralTime = {
|
||||
{5, NULL, NULL, init_si, NULL}, read_si
|
||||
};
|
||||
epicsExportAddress(dset, devSiGeneralTime);
|
||||
Reference in New Issue
Block a user