228 lines
6.7 KiB
C
228 lines
6.7 KiB
C
/* $Id$
|
||
* Author: Roger A. Cole
|
||
* Date: 12-04-90
|
||
*
|
||
* Experimental Physics and Industrial Control System (EPICS)
|
||
*
|
||
* Copyright 1991-92, the Regents of the University of California,
|
||
* and the University of Chicago Board of Governors.
|
||
*
|
||
* This software was produced under U.S. Government contracts:
|
||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||
*
|
||
* Initial development by:
|
||
* The Controls and Automation Group (AT-8)
|
||
* Ground Test Accelerator
|
||
* Accelerator Technology Division
|
||
* Los Alamos National Laboratory
|
||
*
|
||
* Co-developed with
|
||
* The Controls and Computing Group
|
||
* Accelerator Systems Division
|
||
* Advanced Photon Source
|
||
* Argonne National Laboratory
|
||
*
|
||
* Modification Log:
|
||
* -----------------
|
||
* .00 12-04-90 rac initial version
|
||
* .01 06-18-91 rac installed in SCCS
|
||
* .02 06-19-91 rac replace <fields.h> with <alarm.h>
|
||
* .03 02-27-92 rac do ts rounding here instead of sydSubr.c
|
||
*
|
||
* make options
|
||
* -DvxWorks makes a version for VxWorks
|
||
* -DNDEBUG don't compile assert() checking
|
||
* -DDEBUG compile various debug code, including checks on
|
||
* malloc'd memory
|
||
*/
|
||
/*+/mod***********************************************************************
|
||
* TITLE sydSubrPFO.c - acquire synchronous samples from `gsd_...' routines
|
||
*
|
||
* DESCRIPTION
|
||
*
|
||
*-***************************************************************************/
|
||
#include <genDefs.h>
|
||
#define SYD_PRIVATE
|
||
#include <sydDefs.h>
|
||
#include <alarm.h>
|
||
#ifndef INC_tsDefs_h
|
||
# include <tsDefs.h>
|
||
#endif
|
||
#ifndef INCLcadefh
|
||
# include <cadef.h>
|
||
#endif
|
||
#include <gsd_sync_defs.h>
|
||
#define PFO_CHAN_DEF
|
||
#include <pfoPlotDefs.h>
|
||
|
||
#ifdef vxWorks
|
||
# include <vxWorks.h>
|
||
# include <ioLib.h> /* for O_RDWR and O_RDONLY definitions */
|
||
# include <stdioLib.h>
|
||
#else
|
||
# include <stdio.h>
|
||
# include <sys/file.h> /* for O_RDWR and O_RDONLY definitions */
|
||
#endif
|
||
|
||
long sydPFOFunc();
|
||
long sydPFOFuncGetGR();
|
||
|
||
long
|
||
sydOpenPFO(ppSspec, pHandle)
|
||
SYD_SPEC **ppSspec; /* O pointer to synchronous set spec pointer */
|
||
void *pHandle; /* I pointer to handle for "source" */
|
||
{
|
||
long stat;
|
||
|
||
assert(ppSspec != NULL);
|
||
|
||
if ((*ppSspec = (SYD_SPEC *)GenMalloc(sizeof(SYD_SPEC))) == NULL)
|
||
return S_syd_noMem;
|
||
(*ppSspec)->pFunc = sydPFOFunc;
|
||
(*ppSspec)->type = SYD_TY_PFO;
|
||
if ((stat = sydPFOFunc(*ppSspec, NULL, SYD_FC_INIT, pHandle)) != S_syd_OK){
|
||
GenFree((char *)*ppSspec);
|
||
*ppSspec = NULL;
|
||
return stat;
|
||
}
|
||
(*ppSspec)->nInBufs = 2;
|
||
return sydOpen(ppSspec, pHandle);
|
||
}
|
||
/*+/subr**********************************************************************
|
||
* NAME sydPFOFunc - handle gsd_xxx sync data interactions
|
||
*
|
||
* DESCRIPTION
|
||
*
|
||
* sydPFOFunc(pSspec, NULL, SYD_FC_INIT, NULL)
|
||
* sydPFOFunc(pSspec, pSChan, SYD_FC_OPEN, pPfoChan)
|
||
* sydPFOFunc(pSspec, pSChan, SYD_FC_READ, NULL)
|
||
* sydPFOFunc(pSspec, pSChan, SYD_FC_POSITION, NULL)
|
||
* sydPFOFunc(pSspec, pSChan, SYD_FC_CLOSE, NULL)
|
||
* sydPFOFunc(pSspec, NULL, SYD_FC_FILEINFO, NULL)
|
||
* sydPFOFunc(pSspec, NULL, SYD_FC_WRAPUP, NULL)
|
||
*
|
||
* RETURNS
|
||
* S_syd_OK, or
|
||
* other code indicating error
|
||
*
|
||
* BUGS
|
||
* o text
|
||
*
|
||
* SEE ALSO
|
||
*
|
||
* EXAMPLE
|
||
*
|
||
*-*/
|
||
long
|
||
sydPFOFunc(pSspec, pStruct, funcCode, pArg)
|
||
SYD_SPEC *pSspec; /* IO pointer to synchronous set spec */
|
||
void *pStruct; /* IO pointer to data struct used by funcCode */
|
||
enum sydFuncCode funcCode;/* I function code */
|
||
void *pArg; /* I pointer to arg, as required by funcCode */
|
||
{
|
||
SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */
|
||
PFO_CHAN *pPChan; /* pointer to pfo channel struct */
|
||
struct gsd_sync_data *pSyn; /* pointer to pfo sync data struct */
|
||
long retStat=S_syd_OK;
|
||
int bufNum, nBytes;
|
||
|
||
pSChan = (SYD_CHAN *)pStruct;
|
||
|
||
if (funcCode == SYD_FC_INIT) {
|
||
pSspec->pHandle = NULL;
|
||
}
|
||
else if (funcCode == SYD_FC_OPEN) {
|
||
pPChan = (PFO_CHAN *)pArg;
|
||
pSChan->pHandle = (void *)pPChan->pGsd;
|
||
pSChan->dbfType = ca_field_type(pPChan->pGsd->pChid);
|
||
pSChan->dbrType = pPChan->pGsd->time_type;
|
||
assert(dbr_type_is_TIME(pSChan->dbrType));
|
||
pSChan->elCount = pPChan->pGsd->count;
|
||
sydPFOFuncGetGR(pSspec, pSChan, pPChan);
|
||
}
|
||
else if (funcCode == SYD_FC_READ) {
|
||
pSyn = (struct gsd_sync_data *)pSChan->pHandle;
|
||
if (pSyn->svalid != 0) {
|
||
bufNum = NEXT_INBUF(pSChan, pSChan->lastInBuf);
|
||
nBytes = dbr_size_n(pSChan->dbrType, pSChan->elCount);
|
||
bcopy((char *)pSyn->pSdata, (char *)pSChan->pInBuf[bufNum], nBytes);
|
||
pSChan->inStatus[bufNum] = SYD_B_FULL;
|
||
pSChan->lastInBuf = bufNum;
|
||
if (pSChan->firstInBuf < 0)
|
||
pSChan->firstInBuf = bufNum;
|
||
if (pSspec->roundNsec > 0) {
|
||
sydTsRound(&pSChan->pInBuf[bufNum]->tfltval.stamp,
|
||
pSspec->roundNsec);
|
||
}
|
||
}
|
||
}
|
||
else if (funcCode == SYD_FC_POSITION) {
|
||
; /* no action */
|
||
}
|
||
else if (funcCode == SYD_FC_CLOSE) {
|
||
; /* no action */
|
||
}
|
||
else if (funcCode == SYD_FC_FILEINFO) {
|
||
; /* no action */
|
||
}
|
||
else if (funcCode == SYD_FC_WRAPUP) {
|
||
pSspec->pHandle = NULL;
|
||
}
|
||
|
||
return retStat;
|
||
}
|
||
|
||
static long
|
||
sydPFOFuncGetGR(pSspec, pSChan, pPChan)
|
||
SYD_SPEC *pSspec; /* pointer to syncSet specification */
|
||
SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */
|
||
PFO_CHAN *pPChan; /* pointer to pfo channel struct */
|
||
{
|
||
int i;
|
||
|
||
if (pSChan->dbrType == DBR_TIME_FLOAT) {
|
||
assert(pPChan->dbrGrType == DBR_GR_FLOAT ||
|
||
pPChan->dbrGrType == DBR_CTRL_FLOAT);
|
||
pSChan->grBuf.gfltval = pPChan->pDbrGr->gfltval;
|
||
pSChan->dbrGrType = DBR_GR_FLOAT;
|
||
}
|
||
else if (pSChan->dbrType == DBR_TIME_SHORT) {
|
||
assert(pPChan->dbrGrType == DBR_GR_SHORT ||
|
||
pPChan->dbrGrType == DBR_CTRL_SHORT);
|
||
pSChan->grBuf.gshrtval = pPChan->pDbrGr->gshrtval;
|
||
pSChan->dbrGrType = DBR_GR_SHORT;
|
||
}
|
||
else if (pSChan->dbrType == DBR_TIME_DOUBLE) {
|
||
assert(pPChan->dbrGrType == DBR_GR_DOUBLE ||
|
||
pPChan->dbrGrType == DBR_CTRL_DOUBLE);
|
||
pSChan->grBuf.gdblval = pPChan->pDbrGr->gdblval;
|
||
pSChan->dbrGrType = DBR_GR_DOUBLE;
|
||
}
|
||
else if (pSChan->dbrType == DBR_TIME_LONG) {
|
||
assert(pPChan->dbrGrType == DBR_GR_LONG ||
|
||
pPChan->dbrGrType == DBR_CTRL_LONG);
|
||
pSChan->grBuf.glngval = pPChan->pDbrGr->glngval;
|
||
pSChan->dbrGrType = DBR_GR_LONG;
|
||
}
|
||
else if (pSChan->dbrType == DBR_TIME_STRING) {
|
||
assert(pPChan->dbrGrType == DBR_GR_STRING ||
|
||
pPChan->dbrGrType == DBR_CTRL_STRING);
|
||
pSChan->grBuf.gstrval = pPChan->pDbrGr->gstrval;
|
||
pSChan->dbrGrType = DBR_GR_STRING;
|
||
}
|
||
else if (pSChan->dbrType == DBR_TIME_ENUM) {
|
||
assert(pPChan->dbrGrType == DBR_GR_ENUM ||
|
||
pPChan->dbrGrType == DBR_CTRL_ENUM);
|
||
pSChan->grBuf.genmval = pPChan->pDbrGr->genmval;
|
||
pSChan->dbrGrType = DBR_GR_ENUM;
|
||
}
|
||
else if (pSChan->dbrType == DBR_TIME_CHAR) {
|
||
assert(pPChan->dbrGrType == DBR_GR_CHAR ||
|
||
pPChan->dbrGrType == DBR_CTRL_CHAR);
|
||
pSChan->grBuf.gchrval = pPChan->pDbrGr->gchrval;
|
||
pSChan->dbrGrType = DBR_GR_FLOAT;
|
||
}
|
||
return S_syd_OK;
|
||
}
|