#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <epicsExport.h>
#include <dbAccess.h>
#include <devSup.h>
#include <recGbl.h>
#include <aiRecord.h>
// ADCPi definitions
#define ADC_1 0x68
#define ADC_2 0x69
#define ADC_CHANNEL1 0x98
#define ADC_CHANNEL2 0xB8
#define ADC_CHANNEL3 0xD8
#define ADC_CHANNEL4 0xF8
static long init_record(aiRecord *pai);
static long read_ai(aiRecord *pai);
struct adcPiChannel {
unsigned int channel;
};
int getadc (int chn){
unsigned int fh,dummy, adc, adc_channel;
// double val;
__u8 res[4];
printf(" Read channel Nr: %d\n", chn);
switch (chn){
case 1: { adc=ADC_1; adc_channel=ADC_CHANNEL1; }; break;
case 2: { adc=ADC_1; adc_channel=ADC_CHANNEL2; }; break;
case 3: { adc=ADC_1; adc_channel=ADC_CHANNEL3; }; break;
case 4: { adc=ADC_1; adc_channel=ADC_CHANNEL4; }; break;
case 5: { adc=ADC_2; adc_channel=ADC_CHANNEL1; }; break;
case 6: { adc=ADC_2; adc_channel=ADC_CHANNEL2; }; break;
case 7: { adc=ADC_2; adc_channel=ADC_CHANNEL3; }; break;
case 8: { adc=ADC_2; adc_channel=ADC_CHANNEL4; }; break;
default: { adc=ADC_1; adc_channel=ADC_CHANNEL1; }; break;
}
fh = open("/dev/i2c-1", O_RDWR);
ioctl(fh,I2C_SLAVE,adc);
i2c_smbus_write_byte (fh, adc_channel);
usleep (50000);
i2c_smbus_read_i2c_block_data(fh,adc_channel,4,res);
usleep(50000);
close (fh);
dummy = (res[0]<<8|res[1]);
if (dummy>=32768) dummy=65536-dummy;
//val = dummy * 0.000154;
// printf(" dummy = %d, val = %lf\n", dummy, val);
//return val;
return dummy;
}
static long init_record(aiRecord *pai)
{
struct adcPiChannel* priv;
unsigned long channel;
priv=malloc(sizeof(struct adcPiChannel));
if(!priv){
recGblRecordError(S_db_noMemory, (void*)pai,
"devAoTimebase failed to allocate private struct");
return S_db_noMemory;
}
recGblInitConstantLink(&pai->inp,DBF_ULONG,&channel);
priv->channel=channel;
pai->dpvt=priv;
return 0;
}
static long read_ai(aiRecord *pai)
{
struct adcPiChannel* priv=pai->dpvt;
pai->rval = getadc(priv->channel);
return 0;
}
struct {
long num;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_ai;
DEVSUPFUN special_linconv;
} devAiAdcPi = {
6, /* space for 6 functions */
NULL,
NULL,
init_record,
NULL,
read_ai,
NULL
};
epicsExportAddress(dset,devAiAdcPi);