/** @brief device support adcPi
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <devSup.h>
#include <recGbl.h>
#include <alarm.h>
#include <errlog.h>
#include <aiRecord.h>
#include <epicsExport.h>
#include "drvAdcPi.h"
typedef struct {
adcPiCard* card;
int signal;
} adcPiAiPrivate;
long adcPiInitRecordAi (aiRecord *record);
long adcPiReadAi (aiRecord *record);
long adcPiSpecialLinconvAi (aiRecord *record, int after);
struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_ai;
DEVSUPFUN special_linconv;
} adcPiAi = {
6,
NULL,
NULL,
adcPiInitRecordAi,
NULL,
adcPiReadAi,
adcPiSpecialLinconvAi
};
epicsExportAddress (dset, adcPiAi);
/** @brief init record
*
*/
long adcPiInitRecordAi (aiRecord *record)
{
adcPiAiPrivate *priv;
epicsUInt16 initval;
adcPiCard* card;
int signal;
if (record->inp.type != VME_IO) {
errlogSevPrintf (errlogFatal, "adcPiInitRecordAi %s: illegal INP link type\n", record->name);
return -1;
}
card = adcPiOpen (record->inp.value.vmeio.card);
if (!card) {
errlogSevPrintf (errlogFatal, "adcPiInitRecordAi %s: invalid card number %d\n", record->name, record->inp.value.vmeio.card);
return S_dev_noDevice;
}
signal = record->inp.value.vmeio.signal;
if (signal < 0 || signal >= ADC_PI_MAX_CHANNEL) {
errlogSevPrintf (errlogFatal, "adcPiInitRecordAi %s: invalid signal number %d\n", record->name, signal);
return S_dev_badSignalNumber;
}
priv = (adcPiAiPrivate*) malloc (sizeof (adcPiAiPrivate));
if (!priv) {
errlogSevPrintf (errlogFatal, "adcPiInitRecordAi %s: out of memory\n", record->name);
return S_dev_noMemory;
}
priv->card = card;
priv->signal = signal;
record->dpvt = priv;
// printf(" priv at @%p [%d]\n", priv, sizeof (adcPiAiPrivate) );
adcPiSpecialLinconvAi (record, TRUE);
adcPiGet (card, signal, &initval);
record->rval = initval;
return 0;
}
long adcPiReadAi (aiRecord *record)
{
adcPiAiPrivate *priv = (adcPiAiPrivate*) record->dpvt;
int status;
// printf("ReadAi: priv at @%p [%d]\n", priv, sizeof (adcPiAiPrivate) );
if (!priv) {
recGblSetSevr (record, UDF_ALARM, INVALID_ALARM);
errlogSevPrintf (errlogFatal, "adcPiReadAi %s: record not initialized correctly\n", record->name);
return -1;
}
unsigned short value;
status = adcPiGet (priv->card, priv->signal, &value);
if (status) {
errlogSevPrintf (errlogFatal, "adcPiReadAi %s: adcPiGet failes: error code 0x%x\n", record->name, status);
recGblSetSevr (record, READ_ALARM, INVALID_ALARM);
}
record->rval = value;
return status; // 2 do not convert
}
long adcPiSpecialLinconvAi (aiRecord *record, int after)
{
if (after) {
// printf(" In convert ....\n");
// Check/Check ...
// MAX_CODE_12BIT / 2048 Volt
//record->eoff = ( 8191 * record->egul - -8192 * record->eguf) / (8191 - 8192);
record->eoff = 0;
record->eslo = 0.000250; // 205 uV (record->eguf - record->egul)/ (8191 - 8192);
}
return 0;
}