From 90a53b60c582e27f6848a8e98a83f571e84ef181 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 28 Apr 2008 16:10:49 +0000 Subject: [PATCH] Major cleanup, rewrote some parts completely. --- src/dev/softDev/devGeneralTime.c | 467 +++++++++++++++---------------- 1 file changed, 229 insertions(+), 238 deletions(-) diff --git a/src/dev/softDev/devGeneralTime.c b/src/dev/softDev/devGeneralTime.c index 8e6a5dd21..4ac32398b 100644 --- a/src/dev/softDev/devGeneralTime.c +++ b/src/dev/softDev/devGeneralTime.c @@ -1,262 +1,253 @@ -/*************************************************************************** - * File: devGeneralTime.c - * Author: Sheng Peng - * Institution: Oak Ridge National Laboratory / SNS Project +/*************************************************************************\ +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +/* Id$ */ +/* + * Original Author: Sheng Peng, ORNL / SNS Project * Date: 07/2004 - * Version: 1.2 * - * EPICS device layer support for general EPICS timestamp support + * EPICS device support for general timestamp support * * Integrated into base by Peter Denison, Diamond Light Source - ****************************************************************************/ + */ -/* Include header files */ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#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 -#include - -#include -#include -#include -#include - -#include "epicsGeneralTime.h" - -int GENERALTIME_DEV_DEBUG=0; - -/* define function flags */ -typedef enum { - GTIM_AI_CURRENT, - GTIM_BO_RSTERRCNT, - GTIM_LI_GETERRCNT, - GTIM_SI_BESTTCP, - GTIM_SI_BESTTEP -} GTIMFUNC; +#include "aiRecord.h" +#include "boRecord.h" +#include "longinRecord.h" +#include "stringinRecord.h" -/* define parameter check for convinence */ -#define CHECK_AIPARM(PARM,VAL)\ - if (!strncmp(pai->inp.value.instio.string,(PARM),strlen((PARM)))) {\ - pai->dpvt=(void *)VAL;\ - return (0);\ - } -#define CHECK_BOPARM(PARM,VAL)\ - if (!strncmp(pbo->out.value.instio.string,(PARM),strlen((PARM)))) {\ - pbo->dpvt=(void *)VAL;\ - paramOK=1;\ - } -#define CHECK_LIPARM(PARM,VAL)\ - if (!strncmp(pli->inp.value.instio.string,(PARM),strlen((PARM)))) {\ - pli->dpvt=(void *)VAL;\ - return (0);\ - } -#define CHECK_SIPARM(PARM,VAL)\ - if (!strncmp(psi->inp.value.instio.string,(PARM),strlen((PARM)))) {\ - psi->dpvt=(void *)VAL;\ - return (0);\ - } +/********* ai record **********/ +static struct ai_channel { + char *name; + int (*get)(double *); +} ai_channels[] = { + {"TIME", generalTimeGetCurrentDouble}, +}; -/* function prototypes */ -static long init(int pass); +static long init_ai(aiRecord *prec) +{ + int i; -static long init_ai(struct aiRecord *pai); -static long read_ai(struct aiRecord *pai); + 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; + } -static long init_bo(struct boRecord *pbo); -static long write_bo(struct boRecord *pbo); + 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; + } + } -static long init_li(struct longinRecord *pli); -static long read_li(struct longinRecord *pli); + recGblRecordError(S_db_badField, (void *)prec, + "devAiGeneralTime::init_ai: Bad parm"); + prec->pact = TRUE; + prec->dpvt = NULL; + return S_db_badField; +} -static long init_si(struct stringinRecord *psi); -static long read_si(struct stringinRecord *psi); +static long read_ai(aiRecord *prec) +{ + struct ai_channel *pchan = (struct ai_channel *)prec->dpvt; -/* global struct for devSup */ -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_write; - DEVSUPFUN special_linconv;} GTIM_DEV_SUP_SET; + if (!pchan) return -1; -GTIM_DEV_SUP_SET devAiGeneralTime= {6, NULL, init, init_ai, NULL, read_ai, NULL}; -GTIM_DEV_SUP_SET devBoGeneralTime= {6, NULL, NULL, init_bo, NULL, write_bo, NULL}; -GTIM_DEV_SUP_SET devLiGeneralTime= {6, NULL, NULL, init_li, NULL, read_li, NULL}; -GTIM_DEV_SUP_SET devSiGeneralTime= {6, NULL, NULL, init_si, NULL, read_si, NULL}; + 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 struct bo_channel { + char *name; + void (*put)(); +} bo_channels[] = { + {"RSTERRCNT", generalTimeResetErrorCounts}, +}; + +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(prec->val); + return 0; +} + +struct { + dset common; + DEVSUPFUN read_write; +} devBoGeneralTime = { + {5, NULL, NULL, init_bo, NULL}, write_bo +}; epicsExportAddress(dset, devBoGeneralTime); + + +/******* longin record *************/ +static struct li_channel { + char *name; + int (*get)(void); +} li_channels[] = { + {"GETERRCNT", generalTimeGetErrorCounts}, +}; + +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 struct si_channel { + char *name; + void (*get)(char *buf); +} si_channels[] = { + {"BESTTCP", generalTimeGetBestTcp}, + {"BESTTEP", generalTimeGetBestTep}, +}; + +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; + + if (!pchan) return -1; + + pchan->get(prec->val); + prec->udf = FALSE; + return 0; +} + +struct { + dset common; + DEVSUPFUN read_write; +} devSiGeneralTime = { + {5, NULL, NULL, init_si, NULL}, read_si +}; epicsExportAddress(dset, devSiGeneralTime); - -/* function implementation */ - -static long init(int pass) -{ - if(pass) return 0; - return 0; -} - -static long init_ai( struct aiRecord *pai) -{ - if (pai->inp.type!=INST_IO) - { - recGblRecordError(S_db_badField, (void *)pai, - "devAiGeneralTime Init_record, Illegal INP"); - pai->pact=TRUE; - return (S_db_badField); - } - - CHECK_AIPARM("TIME", GTIM_AI_CURRENT) - /* reach here, bad parm */ - recGblRecordError(S_db_badField, (void *)pai, - "devAiGeneralTime Init_record, bad parm"); - pai->pact=TRUE; - return (S_db_badField); -} - -static long read_ai(struct aiRecord *pai) -{ - int status=-1; - double temp; - - switch ((int)pai->dpvt) - { - case GTIM_AI_CURRENT: - status=generalTimeGetCurrentDouble(&temp); - break; - default: - return -1; - } - if (status==0) - { - pai->val=temp; - pai->udf=FALSE; - return 2;/******** not convert ****/ - } - else - { - pai->udf=TRUE; - recGblSetSevr(pai,READ_ALARM,INVALID_ALARM); - return -1; - } -} - -/*********bo record **********/ -static long init_bo(struct boRecord *pbo) -{ - int paramOK=0; - - if (pbo->out.type!=INST_IO) - { - recGblRecordError(S_db_badField, (void *)pbo, - "devBoGeneralTime Init_record, Illegal OUT"); - pbo->pact=TRUE; - return (S_db_badField); - } - CHECK_BOPARM("RSTERRCNT", GTIM_BO_RSTERRCNT) - if (!paramOK) - { - recGblRecordError(S_db_badField, (void *)pbo, - "devBoGeneralTime Init_record, bad parm"); - pbo->pact=TRUE; - return (S_db_badField); - } - - pbo->mask=0; /** when convert rval from val,keep them same **/ - - return 2; /** don't convert rval to val **/ -} - -static long write_bo(struct boRecord *pbo) -{ - switch ((int)pbo->dpvt) - { - case GTIM_BO_RSTERRCNT: - generalTimeResetErrorCounts(); - break; - } - return 0; -} - - -/*******longin record *************/ -static long init_li(struct longinRecord *pli) -{ - if (pli->inp.type!=INST_IO) - { - recGblRecordError(S_db_badField, (void *)pli, - "devLiGeneralTime Init_record, Illegal INP"); - pli->pact=TRUE; - return (S_db_badField); - } - CHECK_LIPARM("GETERRCNT", GTIM_LI_GETERRCNT) - /* reach here, bad parm */ - recGblRecordError(S_db_badField, (void *)pli, - "devLiGeneralTime Init_record, bad parm"); - pli->pact=TRUE; - return (S_db_badField); -} - -static long read_li(struct longinRecord *pli) -{ - switch ((int)pli->dpvt) - { - case GTIM_LI_GETERRCNT: - pli->val=generalTimeGetErrorCounts(); - break; - default: - return -1; - } - return 0; -} - - -/********** stringin record **********/ -static long init_si(struct stringinRecord *psi) -{ - if (psi->inp.type!=INST_IO) - { - recGblRecordError(S_db_badField, (void *)psi, - "devSiGeneralTime Init_record, Illegal INP"); - psi->pact=TRUE; - return (S_db_badField); - } - CHECK_SIPARM("BESTTCP", GTIM_SI_BESTTCP) - CHECK_SIPARM("BESTTEP", GTIM_SI_BESTTEP) - /* reach here, bad parm */ - recGblRecordError(S_db_badField, (void *)psi, - "devSiGeneralTime Init_record, bad parm"); - psi->pact=TRUE; - return (S_db_badField); -} - -static long read_si(struct stringinRecord *psi) -{ - switch ((int)psi->dpvt) - { - case GTIM_SI_BESTTCP: - generalTimeGetBestTcp(psi->val); - break; - case GTIM_SI_BESTTEP: - generalTimeGetBestTep(psi->val); - break; - } - return 0; -} -