kstmApp/src/devadcpi.c
author Heinz Junkes <junkes@fhi-berlin.mpg.de>
Mon, 09 Jul 2018 13:36:24 +0200
changeset 4 f7598b2df637
parent 1 7029db7ac3db
permissions -rw-r--r--
update

#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);