kstmApp/src/devAdcPi.c
author Heinz Junkes <junkes@fhi-berlin.mpg.de>
Tue, 19 Jan 2016 10:54:27 +0100
changeset 2 3b3af1ff2783
permissions -rw-r--r--
add driver abd device support for adcPi

/** @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;
}