Files
epics-base/src/rec/subArrayRecord.c
Andrew Johnson 9ab6f89604 Clean up epicsExport.h includes
Mostly in record and device support, this commit puts
the include in the right place and moves some other
includes around to get the order right.
2013-11-20 16:21:10 -06:00

311 lines
7.4 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*************************************************************************\
* Copyright (c) 2002 Lawrence Berkeley Laboratory,The Control Systems
* Group, Systems Engineering Department
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* $Revision-Id$ */
/* recSubArray.c - Record Support Routines for SubArray records
*
*
* Author: Carl Lionberger
* Date: 090293
*
* NOTES:
* Derived from waveform record.
* Modification Log:
* -----------------
*/
#include <stddef.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "dbDefs.h"
#include "epicsPrint.h"
#include "alarm.h"
#include "dbAccess.h"
#include "dbEvent.h"
#include "dbFldTypes.h"
#include "dbScan.h"
#include "devSup.h"
#include "errMdef.h"
#include "recSup.h"
#include "recGbl.h"
#include "cantProceed.h"
#define GEN_SIZE_OFFSET
#include "subArrayRecord.h"
#undef GEN_SIZE_OFFSET
#include "epicsExport.h"
/* Create RSET - Record Support Entry Table*/
#define report NULL
#define initialize NULL
static long init_record(subArrayRecord *prec, int pass);
static long process(subArrayRecord *prec);
#define special NULL
#define get_value NULL
static long cvt_dbaddr(DBADDR *paddr);
static long get_array_info(DBADDR *paddr, long *no_elements, long *offset);
static long put_array_info(DBADDR *paddr, long nNew);
static long get_units(DBADDR *paddr, char *units);
static long get_precision(DBADDR *paddr, long *precision);
#define get_enum_str NULL
#define get_enum_strs NULL
#define put_enum_str NULL
static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd);
static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd);
#define get_alarm_double NULL
rset subArrayRSET={
RSETNUMBER,
report,
initialize,
init_record,
process,
special,
get_value,
cvt_dbaddr,
get_array_info,
put_array_info,
get_units,
get_precision,
get_enum_str,
get_enum_strs,
put_enum_str,
get_graphic_double,
get_control_double,
get_alarm_double
};
epicsExportAddress(rset,subArrayRSET);
struct sadset { /* subArray dset */
long number;
DEVSUPFUN dev_report;
DEVSUPFUN init;
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_sa; /*returns: (-1,0)=>(failure,success)*/
};
static void monitor(subArrayRecord *prec);
static long readValue(subArrayRecord *prec);
static long init_record(subArrayRecord *prec, int pass)
{
struct sadset *pdset;
if (pass==0){
if (prec->malm <= 0)
prec->malm = 1;
if (prec->ftvl > DBF_ENUM)
prec->ftvl = DBF_UCHAR;
prec->bptr = callocMustSucceed(prec->malm, dbValueSize(prec->ftvl),
"subArrayRecord calloc failed");
prec->nord = 0;
return 0;
}
/* must have dset defined */
if (!(pdset = (struct sadset *)(prec->dset))) {
recGblRecordError(S_dev_noDSET,(void *)prec,"sa: init_record");
return S_dev_noDSET;
}
/* must have read_sa function defined */
if ( (pdset->number < 5) || (pdset->read_sa == NULL) ) {
recGblRecordError(S_dev_missingSup,(void *)prec,"sa: init_record");
return S_dev_missingSup;
}
if (pdset->init_record)
return (*pdset->init_record)(prec);
return 0;
}
static long process(subArrayRecord *prec)
{
struct sadset *pdset = (struct sadset *)(prec->dset);
long status;
unsigned char pact=prec->pact;
if ((pdset==NULL) || (pdset->read_sa==NULL)) {
prec->pact=TRUE;
recGblRecordError(S_dev_missingSup, (void *)prec, "read_sa");
return S_dev_missingSup;
}
if (pact && prec->busy) return 0;
status=readValue(prec); /* read the new value */
if (!pact && prec->pact) return 0;
prec->pact = TRUE;
recGblGetTimeStamp(prec);
prec->udf = !!status; /* 0 or 1 */
if (status)
recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM);
monitor(prec);
/* process the forward scan link record */
recGblFwdLink(prec);
prec->pact=FALSE;
return 0;
}
static long cvt_dbaddr(DBADDR *paddr)
{
subArrayRecord *prec = (subArrayRecord *) paddr->precord;
paddr->pfield = prec->bptr;
paddr->no_elements = prec->malm;
paddr->field_type = prec->ftvl;
paddr->field_size = dbValueSize(prec->ftvl);
paddr->dbr_field_type = prec->ftvl;
return 0;
}
static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
{
subArrayRecord *prec = (subArrayRecord *) paddr->precord;
if (prec->udf)
*no_elements = 0;
else
*no_elements = prec->nord;
*offset = 0;
return 0;
}
static long put_array_info(DBADDR *paddr, long nNew)
{
subArrayRecord *prec = (subArrayRecord *) paddr->precord;
if (nNew > prec->malm)
nNew = prec->malm;
prec->nord = nNew;
return 0;
}
static long get_units(DBADDR *paddr, char *units)
{
subArrayRecord *prec = (subArrayRecord *) paddr->precord;
strncpy(units, prec->egu, DB_UNITS_SIZE);
return 0;
}
static long get_precision(DBADDR *paddr, long *precision)
{
subArrayRecord *prec = (subArrayRecord *) paddr->precord;
int fieldIndex = dbGetFieldIndex(paddr);
*precision = prec->prec;
if (fieldIndex != subArrayRecordVAL)
recGblGetPrec(paddr, precision);
return 0;
}
static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
{
subArrayRecord *prec = (subArrayRecord *) paddr->precord;
switch (dbGetFieldIndex(paddr)) {
case subArrayRecordVAL:
pgd->upper_disp_limit = prec->hopr;
pgd->lower_disp_limit = prec->lopr;
break;
case subArrayRecordINDX:
pgd->upper_disp_limit = prec->malm - 1;
pgd->lower_disp_limit = 0;
break;
case subArrayRecordNELM:
pgd->upper_disp_limit = prec->malm;
pgd->lower_disp_limit = 1;
break;
default:
recGblGetGraphicDouble(paddr, pgd);
}
return 0;
}
static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
{
subArrayRecord *prec = (subArrayRecord *) paddr->precord;
switch (dbGetFieldIndex(paddr)) {
case subArrayRecordVAL:
pcd->upper_ctrl_limit = prec->hopr;
pcd->lower_ctrl_limit = prec->lopr;
break;
case subArrayRecordINDX:
pcd->upper_ctrl_limit = prec->malm - 1;
pcd->lower_ctrl_limit = 0;
break;
case subArrayRecordNELM:
pcd->upper_ctrl_limit = prec->malm;
pcd->lower_ctrl_limit = 1;
break;
default:
recGblGetControlDouble(paddr, pcd);
}
return 0;
}
static void monitor(subArrayRecord *prec)
{
unsigned short monitor_mask;
monitor_mask = recGblResetAlarms(prec);
monitor_mask |= (DBE_LOG|DBE_VALUE);
db_post_events(prec, prec->bptr, monitor_mask);
return;
}
static long readValue(subArrayRecord *prec)
{
long status;
struct sadset *pdset = (struct sadset *) (prec->dset);
if (prec->nelm > prec->malm)
prec->nelm = prec->malm;
if (prec->indx >= prec->malm)
prec->indx = prec->malm - 1;
status = (*pdset->read_sa)(prec);
if (prec->nord <= 0)
status = -1;
return status;
}