Exemple #1
0
int init_daq(double min_range, double max_range, int range_update) {
    int i = 0;

    if (!DEV_OPEN) {
        it = comedi_open("/dev/comedi0");
        if (it == NULL) {
            comedi_perror("comedi_open");
            ADC_OPEN = FALSE;
            DEV_OPEN = FALSE;
            return -1;
        }
        DEV_OPEN = TRUE;
    }

    subdev_ai = comedi_find_subdevice_by_type(it, COMEDI_SUBD_AI, subdev_ai);
    if (subdev_ai < 0) {
        return -2;
        ADC_OPEN = FALSE;
    }


    subdev_ao = comedi_find_subdevice_by_type(it, COMEDI_SUBD_AO, subdev_ao);
    if (subdev_ao < 0) {
        HAS_AO = FALSE;
    } else {
        HAS_AO = TRUE;
    }

    printf("Subdev AI  %i ", subdev_ai);
    channels_ai = comedi_get_n_channels(it, subdev_ai);
    printf("Analog  Channels %i ", channels_ai);
    maxdata_ai = comedi_get_maxdata(it, subdev_ai, i);
    printf("Maxdata %i ", maxdata_ai);
    ranges_ai = comedi_get_n_ranges(it, subdev_ai, i);
    printf("Ranges %i ", ranges_ai);
    ad_range = comedi_get_range(it, subdev_ai, i, ranges_ai - 1);
    if (range_update) {
        ad_range->min = min_range;
        ad_range->max = max_range;
    }
    printf(": ad_range .min = %.3f, max = %.3f\n", ad_range->min,
            ad_range->max);

    if (HAS_AO) {
        printf("Subdev AO  %i ", subdev_ao);
        channels_ao = comedi_get_n_channels(it, subdev_ao);
        printf("Analog  Channels %i ", channels_ao);
        maxdata_ao = comedi_get_maxdata(it, subdev_ao, i);
        printf("Maxdata %i ", maxdata_ao);
        ranges_ao = comedi_get_n_ranges(it, subdev_ao, i);
        printf("Ranges %i ", ranges_ao);
        da_range = comedi_get_range(it, subdev_ao, i, ranges_ao - 1);
        printf(": da_range .min = %.3f, max = %.3f\n", da_range->min,
                da_range->max);
    }

    ADC_OPEN = TRUE;
    comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);
    return 0;
}
Exemple #2
0
static int init_board(void)
{
	dev = comedi_open("/dev/comedi0");		
	printf("Comedi device (6071) handle: %p.\n", dev);
	if (!dev){
		printf("Unable to open (6071) %s.\n", "/dev/comedi0");
		return 1;
	}

	subdevai = comedi_find_subdevice_by_type(dev, COMEDI_SUBD_AI, 0);
	if (subdevai < 0) {
		comedi_close(dev);
		printf("AI subdev (6071) %d not found.\n", COMEDI_SUBD_AI);
		return 1;
	}
	comedi_get_krange(dev, subdevai, 0, AI_RANGE, &krangeai);
	maxdatai = comedi_get_maxdata(dev, subdevai, 0);

	subdevao = comedi_find_subdevice_by_type(dev, COMEDI_SUBD_AO, 0);
	if (subdevao < 0) {
		comedi_close(dev);
		printf("AO subdev (6071) %d not found.\n", COMEDI_SUBD_AO);
		return 1;
	}
	comedi_get_krange(dev, subdevao, 0, AO_RANGE, &krangeao);
	maxdatao = comedi_get_maxdata(dev, subdevao, 0);
	return 0;
}
Exemple #3
0
double readpin(int chan)
{
  comedi_t *it;
  lsampl_t data, maxdata;
  comedi_range *rang;
  int readres;
  double outval;

  if((it=comedi_open("/dev/comedi0"))==NULL) {
    printf("fail open");
  }

  comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);

  readres=comedi_data_read(it,subdev,chan,0,aref, & data);
  if(!readres) {
    comedi_perror("comedi_data_read: ");
  }
 

  rang = comedi_get_range(it, subdev, chan, 0);
  maxdata = comedi_get_maxdata(it, subdev, chan);

  outval = comedi_to_phys(data, rang, maxdata);

  printf("data=%d\noutval=%g\nreadres=%d\n",data, outval, readres);

  return outval;
}
Exemple #4
0
 /**
  * @brief AIO_channel Constructor
  * @param dname Device name
  * @param sd    subdevice
  * @param ch    channel
  * @param rng   range
  * @param input true if it's input channel
  * @param uID   channel unique ID
  */
    AIO_channel(QString dname,int sd,int ch, int rng, int input, int uID)
        {
        deviceName=dname;subdevice =sd; Channel=ch; is_input=input;ChannelID=uID;
        rangeN=rng;
        range = comedi_get_range(it,subdevice, Channel,rangeN);
        maxdata = comedi_get_maxdata(it, subdevice,Channel);
        }
Exemple #5
0
/**
 * @brief constructor from the ini file
 *
 * @param keyname Ini file keyword
 * @param input true if it is an input channel
 */
    AIO_channel(QString keyname, int input)
        {
        read_fromIni(keyname, &deviceName, &subdevice, &Channel, &rangeN);
        range = comedi_get_range(it,subdevice, Channel,rangeN);
        maxdata = comedi_get_maxdata(it, subdevice,Channel);
        is_input=input;
        }
Exemple #6
0
ComediChan::ComediChan(comedi_t *dev, unsigned minor, unsigned subdev, unsigned chan, unsigned range, unsigned aref, const double * range_override_min, const double * range_override_max, DAQTaskProxy *daq)
  : m_dev(dev), m_minor(minor), m_subdev(subdev), m_chan(chan), m_range(range), m_aref(aref), daq(daq)
{

  m_isdio = m_isai = m_isao = false;

  int t = comedi_get_subdevice_type(m_dev, m_subdev);
  if (t == COMEDI_SUBD_AO) m_isao = true;
  else if (t == COMEDI_SUBD_AI) m_isai = true;
  else if (t == COMEDI_SUBD_DIO) m_isdio = true;
  else {
    err = "Invalid parameters.";
    return;
  }
  if (range_override_min) m_rangeMin = *range_override_min;
  else {
    comedi_range *r = comedi_get_range(dev, subdev, chan, range);
    if (!r) { err = "Invalid parameters."; return; }
    m_rangeMin = r->unit == UNIT_mA ? r->min*1e3 : r->min;
  }
  if (range_override_max) m_rangeMax = *range_override_max;
  else {
    comedi_range *r = comedi_get_range(dev, subdev, chan, range);
    if (!r) { err = "Invalid parameters."; return; }
    m_rangeMax = r->unit == UNIT_mA ? r->max*1e3 : r->max;
  }
  m_maxdata = comedi_get_maxdata(dev, subdev, chan);
  if (!m_maxdata) m_maxdata = 1;
  err = "";
}
Exemple #7
0
int init_dio(void)
{
	int i = 0;

	if (!DEV_OPEN) {
		it = comedi_open(comedi_dev);
		if (it == NULL) {
			comedi_perror("comedi_open");
			DIO_OPEN = FALSE;
			DEV_OPEN = FALSE;
			return -1;
		}
		DEV_OPEN = TRUE;
	}

	subdev_dio = comedi_find_subdevice_by_type(it, COMEDI_SUBD_DIO, subdev_dio);
	if (subdev_dio < 0) {
		return -1;
		DIO_OPEN = FALSE;
	}

	printf("Subdev  %i ", subdev_dio);
	channels_dio = comedi_get_n_channels(it, subdev_dio);
	printf("Digital Channels %i ", channels_dio);
	maxdata_dio = comedi_get_maxdata(it, subdev_dio, i);
	printf("Maxdata %i ", maxdata_dio);
	ranges_dio = comedi_get_n_ranges(it, subdev_dio, i);
	printf("Ranges %i \n", ranges_dio);
	DIO_OPEN = TRUE;
	return 0;
}
Exemple #8
0
bool ComediAnalogOutputHardCal::initialise()
{
        // get physical data range for subdevice (min, max, phys. units)
        m_dataRange = comedi_get_range(m_device, m_subdevice, m_channels[0], m_range);
        Logger(Debug, "Range for 0x%x (%s):\n\tmin = %g\n\tmax = %g\n", m_dataRange,
                        (m_dataRange->unit == UNIT_volt ? "volts" : "milliamps"),
                        m_dataRange->min, m_dataRange->max);
        if(m_dataRange == NULL) {
                comedi_perror(m_deviceFile);
                comedi_close(m_device);
                return false;
        }
        
        // read max data value
        m_maxData = comedi_get_maxdata(m_device, m_subdevice, m_channels[0]);
        Logger(Debug, "Max data = %ld\n", m_maxData);
}
Exemple #9
0
double read_volts(int subdev, int chan, int range) {
  lsampl_t data, maxdata;
  int readres;
  comedi_range *rang;
  double outval;

  comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);
  readres=comedi_data_read(it,subdev,chan,range,aref, & data);
  if(!readres) {
    comedi_perror("comedi_data_read: ");
  }
  rang = comedi_get_range(it, subdev, chan, range);
  maxdata = comedi_get_maxdata(it, subdev, chan);
  outval = comedi_to_phys(data, rang, maxdata);
  //printf("data=%d\noutval=%g\nreadres=%d\n",data, outval, readres);
  return outval;

}
Exemple #10
0
int init_daq(void)
{
	int i = 0, range_index = 0;
	comedi_range *ad_range;

	if (!DEV_OPEN) {
		it = comedi_open(comedi_dev);
		if (it == NULL) {
			comedi_perror("comedi_open");
			ADC_OPEN = FALSE;
			DEV_OPEN = FALSE;
			HAVE_DIO = FALSE;
			HAVE_AI = FALSE;
			return -1;
		}
		DEV_OPEN = TRUE;
	}

	subdev_ai = comedi_find_subdevice_by_type(it, COMEDI_SUBD_AI, subdev_ai);
	if (subdev_ai < 0) {
		return -1;
		ADC_OPEN = FALSE;
	}

	printf("Subdev  %i ", subdev_ai);
	channels_ai = comedi_get_n_channels(it, subdev_ai);
	printf("Analog  Channels %i ", channels_ai);
	maxdata_ai = comedi_get_maxdata(it, subdev_ai, i);
	printf("Maxdata %i ", maxdata_ai);
	ranges_ai = comedi_get_n_ranges(it, subdev_ai, i);
	printf("Ranges %i ", ranges_ai);

	for (range_index = 0; range_index < ranges_ai; range_index++) {
		ad_range = comedi_get_range(it, subdev_ai, i, range_index);
		printf(": range %i, min = %.1f, max = %.1f ", range_index,
		ad_range->min, ad_range->max);
	}
	printf("\n");

	ADC_OPEN = TRUE;
	comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);
	return 0;
}
Exemple #11
0
int setup_read_wave(int subd, int chan, int range, int npnts) {
  //  assert(it!=NULL);

  printf("setup_read_wave...");fflush(stdout);
  int ret;
  int wv_n=++cmd->chanlist_len, wv_i=wv_n-1;
  lsampl_t data;
  //printf("wv_i %d \n", wv_i);

  ///assert(cmd!=NULL);

  if(cmd->chanlist==NULL) {
    cmd->chanlist=malloc(sizeof(unsigned int));
  } else {
    if(realloc(cmd->chanlist, (wv_n)*sizeof(unsigned int))==NULL) 
      { printf("realloc cmd fail \n"); return -1;}
  }
  cmd->chanlist[wv_i]= CR_PACK(chan,range,aref);
  if(npnts>cmd->stop_arg) cmd->stop_arg=npnts;

  cmd->scan_end_arg=wv_n;

  //test_board_read(it);

  comedi_command_test(it,cmd);
  ret=comedi_command_test(it,cmd);
  if(ret!=0){
    comedi_perror("comedi_command_test fail on read");
    return -1;
  }
  //test_board_read(it);

  inp_res[wv_i]=malloc(npnts*sizeof(double));
  inp_rang[wv_i]=comedi_get_range(it, subd, chan, range);
  inp_maxdata[wv_i]=comedi_get_maxdata(it, subd, chan);
  comedi_data_read(it,subd,chan,range,aref, & data);
  //printf("found sdtype %d \n", comedi_find_subdevice_by_type(it, COMEDI_SUBD_AI,0));

  //printf("setup subd %d chan %d rng %d:  data=%d outval=%g\n",subd, chan, range, data, comedi_to_phys(data, inp_rang[wv_i], inp_maxdata[wv_i]));
  printf("done\n");fflush(stdout);

  return wv_i;
}
Exemple #12
0
static void mdlOutputs(SimStruct *S, int_T tid)
{
  double *y = ssGetOutputPortRealSignal(S,0);

#ifndef MATLAB_MEX_FILE
  unsigned int channel = (unsigned int)COMEDI_CHANNEL;
  unsigned int range   = (unsigned int)COMEDI_RANGE;
  unsigned int aref    = (unsigned int)COMEDI_REFERENCE - 1;
  void *dev        = (void *)ssGetPWork(S)[0];
  int subdev       = ssGetIWork(S)[0];
  double range_min = ssGetRWork(S)[0];
  double range_max = ssGetRWork(S)[1];
  lsampl_t data, maxdata = comedi_get_maxdata(dev, subdev, COMEDI_CHANNEL);
  double x;
	
  comedi_data_read(dev, subdev, channel, range, aref, &data);
  x = data;
  x /= maxdata;
  x *= (range_max - range_min);
  x += range_min;
  *y = x;
#endif
}
Exemple #13
0
void print_card_info(comedi_t *card)
{

  //We get the number of ranges for this card
  int n_ranges;
  int chan=1;
  n_ranges=comedi_get_n_ranges( card, SUBDEV, chan);
  printf("This card have %d ranges\n",n_ranges);
  int i;
  
  //We display information about these ranges
  comedi_range *act_range;
  for(i=0;i<n_ranges;i++)
    {
      act_range=comedi_get_range( card, SUBDEV, chan,i);
      printf("range %d\t min %f\t max %f\t unit: %s\n",i,act_range->min,act_range->max,display_unit(act_range->unit));
    }

  //We get the maxdata
  int maxdata;
  maxdata=comedi_get_maxdata(card,SUBDEV,chan);
  printf("maximum data value %d\n",maxdata);

}
Exemple #14
0
static long dsetInit_devAoSyncComedi (aoRecord *pao) {
  CONTEXT *p_myContext;
  COMEDIDEV_AO *p_myAnalogOutput;
  int myPinNumber;
  int myMinorOfDeviceFile;
  double myMinimumVoltage;
  double myMaximumVoltage;
  int myDifferentialMode;

  char  p_myWarmstartFilename[BUFLEN];
  FILE *p_myFileHandle;

  
  packageInfo();
  dsetLog(3, __FILE__ "[%d] -> %s(%s)\n", __LINE__, __func__, pao->name );

  p_myAnalogOutput=(COMEDIDEV_AO *)calloc(1, sizeof(COMEDIDEV_AO));

  if ( sscanf(pao->out.value.instio.string, "modf=%d pn=%d dm=%d",
	 &myMinorOfDeviceFile,
	 &myPinNumber,
         &myDifferentialMode) != 3) {
    dsetLog(1, __FILE__ "[%d] Error: %s\n", __LINE__, pao->name);
    dsetLog(1, __FILE__ "[%d] Error: Couldn't parse parameters\n", __LINE__);
    dsetLog(1, __FILE__ "[%d] Error: >%s<\n", 
		   __LINE__,pao->out.value.instio.string);
    sleep(SLEEPTIME_ERROR);
    return(ERROR);
  }

  p_myAnalogOutput->aref=myDifferentialMode+1; /* always 2 ! */
  
  sprintf(p_myAnalogOutput->p_deviceFilename,"/dev/comedi%d",
			myMinorOfDeviceFile);
  p_myAnalogOutput->device=comedi_open(p_myAnalogOutput->p_deviceFilename);
  p_myAnalogOutput->subdevice=0;
  p_myAnalogOutput->channel=(myPinNumber-1)/2;

  /* Get some values from the drivers	*/
  p_myAnalogOutput->maxdata=comedi_get_maxdata(p_myAnalogOutput->device,
                                               p_myAnalogOutput->subdevice,
                                               p_myAnalogOutput->channel);

  myMinimumVoltage=pao->drvl;
  myMaximumVoltage=pao->drvh;
  p_myAnalogOutput->range=getOptimalOperatingRange(pao);
  p_myAnalogOutput->c_range=comedi_get_range(p_myAnalogOutput->device,
                                             p_myAnalogOutput->subdevice,
                                             p_myAnalogOutput->channel,
                                             p_myAnalogOutput->range);	

  dsetLog(5,__FILE__ "[%d] Parsed options >%s<\n", 
		  __LINE__, pao->out.value.instio.string);
  dsetLog(5,__FILE__ "[%d]   p_deviceFilename  = >%s<\n", 
		  __LINE__, p_myAnalogOutput->p_deviceFilename);
  dsetLog(5,__FILE__ "[%d]   subdevice = %d\n", 
		  __LINE__, p_myAnalogOutput->subdevice);
  dsetLog(5,__FILE__ "[%d]   channel   = %d\n", 
		  __LINE__, p_myAnalogOutput->channel);
  dsetLog(5,__FILE__ "[%d]   range     = %d\n", 
		  __LINE__, p_myAnalogOutput->range);
  dsetLog(5,__FILE__ "[%d]   aref      = %d\n", 
		  __LINE__, p_myAnalogOutput->aref);

  p_myContext=(CONTEXT *)calloc(1,sizeof(CONTEXT));
  p_myContext->p_analogOutput=p_myAnalogOutput;
  p_myContext->minimumVoltage=myMinimumVoltage;
  p_myContext->maximumVoltage=myMaximumVoltage;

  sprintf(p_myWarmstartFilename, WARMSTART_FILE_PREFIX "/%s", pao->name);
  p_myFileHandle=fopen(p_myWarmstartFilename, "r");
  if (p_myFileHandle!=NULL) {
    fscanf(p_myFileHandle, "%lg", &pao->val);
    fclose(p_myFileHandle);
    dsetLog(5, __FILE__ "[%d] Warmstart: %lg (File) -> %s\n",
                __LINE__, pao->val, pao->name);
  } else {
    dsetLog(5, __FILE__ "[%d] Warmstart: %lg (Default) -> %s\n",
                __LINE__, pao->val , pao->name);
  }

  pao->pini=menuYesNoYES;

  pao->dpvt=(void *)p_myContext;

  dsetLog(5, __FILE__ "[%d] Calibration algo  : %d\n", __LINE__, pao->linr);
  dsetLog(5, __FILE__ "[%d] Calibration slope : %lg\n", __LINE__, pao->aslo);
  dsetLog(5, __FILE__ "[%d] Calibration offset: %lg\n", __LINE__, pao->aoff);

  dsetLog(3, __FILE__ "[%d] <- %s\n", __LINE__, __func__ );
  /* Convert according to calibration? NO!*/
  /* Convert update val based on rval and in iwarmstart file is stored val*/
  return(DO_NOT_CONVERT);  
}
Exemple #15
0
int main(int argc, char *argv[])
{
        int ret;
	comedi_insn insn;
	lsampl_t d[5];
	comedi_t *device;

        int freq;

	struct parsed_options options;

	init_parsed_options(&options);
	options.freq = -1;
	// we hijack this option to switch it on or off
	options.n_scan = -1;
	options.value = -1;
	parse_options(&options, argc, argv);

	if ((options.value==-1)&&(options.n_scan==-1)&&(options.freq==-1)) {
		fprintf(stderr,
			"Usage: %s OPTIONS duty_cycle\n"
			"options: \n"
			"     -N 0    switches PWM off\n"
			"     -N 1    switches PWM on\n"
                        "     -N 2    enquires the max value for the duty cycle\n"
			"     -F FREQ sets the PWM frequency\n",
			argv[0]);
	}

        device = comedi_open(options.filename);
        if(!device){
		comedi_perror(options.filename);
		exit(-1);
        }

	options.subdevice = comedi_find_subdevice_by_type(device,COMEDI_SUBD_PWM,0);
	if (options.verbose)
		printf("PWM subdevice autodetection gave subdevice number %d\n",
		       options.subdevice);

	if(options.n_scan==2) {
		printf("%d\n",comedi_get_maxdata(device,options.subdevice,0));
		comedi_close(device);
		exit(0);
	}       

	insn.insn=INSN_CONFIG;
	insn.data=d;
	insn.subdev=options.subdevice;
	insn.chanspec=CR_PACK(0,0,0);

	if(options.n_scan==1) {
		d[0] = INSN_CONFIG_ARM;
		d[1] = 0;
		insn.n=2;
		ret=comedi_do_insn(device,&insn);
		if(ret < 0){
			fprintf(stderr,"Could not switch on:%d\n",ret);
			comedi_perror(options.filename);
			exit(-1);
		}
	}
	if(options.n_scan==0) {
		d[0] = INSN_CONFIG_DISARM;
		d[1] = 0;
		insn.n=1;
		ret=comedi_do_insn(device,&insn);
		if(ret < 0){
			fprintf(stderr,"Could not switch off:%d\n",ret);
			comedi_perror(options.filename);
			exit(-1);
		}
	}
	if(options.freq>0) {
		freq = options.freq;
		d[0] = INSN_CONFIG_PWM_SET_PERIOD;
		d[1] = 1E9/freq;
		insn.n=2;
		ret=comedi_do_insn(device,&insn);
		if(ret < 0){
			fprintf(stderr,"Could set frequ:%d\n",ret);
			comedi_perror(options.filename);
			exit(-1);
		}
	}
		
	d[0] = INSN_CONFIG_GET_PWM_STATUS;
	insn.n=2;
	ret=comedi_do_insn(device,&insn);
	if(ret < 0){
		fprintf(stderr,"Could not get status:%d insn=%d\n",
			ret,
			d[0]);
		comedi_perror(options.filename);
		exit(-1);
	}
	if (options.verbose) {
		if (d[1])
			fprintf(stderr,
				"PWM is on.\n");
		else
			fprintf(stderr,
				"PWM is off.\n");
	}
	d[0] = INSN_CONFIG_PWM_GET_PERIOD;
	insn.n=2;
	ret=comedi_do_insn(device,&insn);
	if(ret < 0){
		fprintf(stderr,"Could get frequ:%d\n",ret);
		comedi_perror(options.filename);
		exit(-1);
	}
	freq = 1E9 / d[1];
	if (options.verbose)
		fprintf(stderr,"PWM frequency is %d\n", freq);

	if (options.value>=0)

		if(comedi_data_write(device,
				     options.subdevice, 
				     options.channel,
				     0,
				     0,
				     options.value)<0)
		{
			fprintf(stderr,"error setting the pwm duty cycle on ");
			comedi_perror(options.filename);
			exit(1);
		}

        return 0;
}
Exemple #16
0
static void init(scicos_block *block)
{
  struct ADCOMDev * comdev = (struct ADCOMDev *) malloc(sizeof(struct ADCOMDev));
  *block->work = (void *)comdev;

  char devName[15];
  char board[50];
  comedi_krange krange;

  comdev->channel = block->ipar[0];
  comdev->range = block->ipar[1];
  comdev->aref = block->ipar[2];
  comdev->index = block->ipar[3];

  sprintf(devName,"/dev/comedi%d", comdev->index);
  if (!ComediDev[comdev->index]) {
    comdev->dev = comedi_open(devName);
    if (!(comdev->dev)) {
      fprintf(stderr, "COMEDI %s open failed\n", devName);
      exit_on_error();
      return;
    }
    rt_comedi_get_board_name(comdev->dev, board);
    printf("COMEDI %s (%s) opened.\n\n", devName, board);
    ComediDev[comdev->index] = comdev->dev;
  } else
    comdev->dev = ComediDev[comdev->index];

  if ((comdev->subdev = comedi_find_subdevice_by_type(comdev->dev, COMEDI_SUBD_AI, 0)) < 0) {
    fprintf(stderr, "Comedi find_subdevice failed (No analog input)\n");
    comedi_close(comdev->dev);
    exit_on_error();
    return;
  }
  if (!ComediDev_AIInUse[comdev->index] && comedi_lock(comdev->dev, comdev->subdev) < 0) {
    fprintf(stderr, "Comedi lock failed for subdevice %d\n", comdev->subdev);
    comedi_close(comdev->dev);
    exit_on_error();
    return;
  }

  if (comdev->channel >= comedi_get_n_channels(comdev->dev, comdev->subdev)) {
    fprintf(stderr, "Comedi channel not available for subdevice %d\n", comdev->subdev);
    comedi_unlock(comdev->dev, comdev->subdev);
    comedi_close(comdev->dev);
    exit_on_error();
    return;
  }
  if ((comedi_get_krange(comdev->dev, comdev->subdev, comdev->channel, comdev->range, &krange)) < 0) {
    fprintf(stderr, "Comedi get_range failed for subdevice %d\n", comdev->subdev);
    comedi_unlock(comdev->dev, comdev->subdev);
    comedi_close(comdev->dev);
    exit_on_error();
    return;
  }
#ifdef SOFTCALIB
  int flags;
  if ((flags = comedi_get_subdevice_flags(comdev->dev, comdev->subdev)) < 0) {
    fprintf(stderr, "Comedi get_subdevice_flags failed for subdevice %d\n", comdev->subdev);
  } else {
    if (flags & SDF_SOFT_CALIBRATED) {/* board uses software calibration */
      if ((comdev->use_softcal = get_softcal_coef(devName, comdev->subdev,
                comdev->channel, comdev->range, 0, comdev->coefficients)) == 0)
        fprintf(stderr, "No software calibration found for AI Channel %d\n",comdev->channel);
    }
  }
#endif

  ComediDev_InUse[comdev->index]++;
  ComediDev_AIInUse[comdev->index]++;
  comdev->maxdata = comedi_get_maxdata(comdev->dev, comdev->subdev, comdev->channel);
  comdev->range_min = (double)(krange.min)*1.e-6;
  comdev->range_max = (double)(krange.max)*1.e-6;
  printf("AI Channel %d - Range : %1.2f [V] - %1.2f [V]%s\n\n", comdev->channel,
    comdev->range_min, comdev->range_max, (comdev->use_softcal)?" Software calibration used":"");
}
Exemple #17
0
/* -------------------------------------------------------------------- */
static long dsetRead_devAiSyncComedi(aiRecord *pai)
{
  CONTEXT  *p_myContext;
  int       mySubdevice;
  int       myChannel;
  int       myRange = 0;
  int       myAnalogReference;
  int       myPinNumber;
  char      p_myDeviceFile[BUFLEN];
  comedi_t *p_myComediFileHandle;
  lsampl_t  data;
  int       maxdata;
  int       ret;

  dsetLog(3, __FILE__ "[%d] -> %s(%s)\n", __LINE__, __func__, pai->name );

  p_myContext = pai->dpvt;
  p_myComediFileHandle = p_myContext->p_comediFileHandle;
  myChannel            = p_myContext->channel;
  myRange              = p_myContext->range;
  myAnalogReference    = p_myContext->analogReference;
  mySubdevice          = p_myContext->subdevice;
  myPinNumber          = p_myContext->pinNumber;
  strcpy(p_myDeviceFile, p_myContext->p_deviceFile);

#if 0
  dsetLog(7,__FILE__ "[%d] Subdevice  = %d PinNumber =%d\n",
          __LINE__,  mySubdevice, myPinNumber);
  dsetLog(7,__FILE__ "[%d] AnalogReference  = %d Channel=%d\n",
          __LINE__,  myAnalogReference, myChannel);

  dsetLog(7, __FILE__ "[%d] -> Range is %d\n", __LINE__, myRange);

#endif

  maxdata = comedi_get_maxdata(p_myComediFileHandle, mySubdevice, myChannel);

#if 0
  dsetLog(7,__FILE__ "[%d] maxdata  = %d pn=%d\n",
          __LINE__,  maxdata, myPinNumber);
  dsetLog(7,__FILE__ "[%d] Data %d -> device %s\n", __LINE__, data, pai->name);

  dsetLog(7,__FILE__ "[%d] New Range  = %lg\n",
          comedi_get_range(p_myComediFileHandle, mySubdevice,
                           myChannel, myRange));
#endif

  ret = comedi_data_read(p_myComediFileHandle, mySubdevice, myChannel,
                         myRange, myAnalogReference, &data);
  if (ret < 0) {
    comedi_perror(p_myDeviceFile);
    dsetLog(1, __FILE__ "[%d] Error: Couldn't read hardware\n", __LINE__);
    sleep(SLEEPTIME_ERROR);

    return(ERROR);
  }

  pai->val = comedi_to_phys(data,
                             comedi_get_range(p_myComediFileHandle, mySubdevice,
                                              myChannel, myRange),
                             maxdata);

  pai->udf = isnan(pai->val);

  dsetLog(7,__FILE__ "[%d] pai->udf is %d \n", __LINE__, pai->udf);

  if (pai->udf) {
    pai->val = 10;
    dsetLog(7,__FILE__ "[%d] Error: Cable is disconnected, please verify\n", __LINE__);
  }

  dsetLog(7,__FILE__ "[%d] val,rval=%lg,%d -> %s\n",
          __LINE__, pai->val, pai->rval, pai->name);

  dsetLog(3,__FILE__ "[%d] <- %s\n", __LINE__, __func__);

  return(NO_AUTOMATIC_CONVERSION);
  /*return(DO_AUTOMATIC_CONVERSION); */
}
ComediScope::ComediScope( ComediRecord *comediRecordTmp, 
			  int channels, 
			  float f, 
			  int port_for_ext_data, 
			  int maxComediDevs,
			  int first_dev_no,
			  int req_sampling_rate,
			  const char* defaultTextStringForMissingExtData,
			  int fftdevnumber, int fftchannel, int fftmaxf
	)
    : QWidget( comediRecordTmp ) {

	channels_in_use = channels;

	tb_init=1;
	tb_counter=tb_init;
	comediRecord=comediRecordTmp;
	// erase plot
	eraseFlag = 1;

	fftdevno = fftdevnumber;
	fftch = fftchannel;
	fftmaxfrequency = fftmaxf;

	// for ASCII
	rec_file=NULL;

	// filename
	rec_filename=new QString();

	// flag if data has been recorded and we need a new filename
	recorded=0;

	if (port_for_ext_data>0) {
		fprintf(stderr,
			"Expecting a connection on TCP port %d. \n"
			"Start your client now, for example: \n"
			"telnet localhost %d\n"
			"Press Ctrl-C to abort.\n",
			port_for_ext_data,
			port_for_ext_data);
		ext_data_receive = new Ext_data_receive(
			port_for_ext_data,
			defaultTextStringForMissingExtData
			);
	} else {
		ext_data_receive = NULL;
	}	


	//////////////////////////////////////////////////////////////

	setAttribute(Qt::WA_OpaquePaintEvent);

	int range = 0;
	int aref = AREF_GROUND;
	// do not produce NAN for out of range behaviour
	comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);

	// create an array which keeps the comedi devices
	dev = new comedi_t*[maxComediDevs];
	for(int devNo=0;devNo<maxComediDevs;devNo++) {
		dev[devNo] = NULL;
	}
	// let's probe how many we have
	nComediDevices = 0;
	for(int devNo=0;devNo<maxComediDevs;devNo++) {
		char filename[128];
		sprintf(filename,"/dev/comedi%d",devNo+first_dev_no);
		dev[devNo] = comedi_open(filename);
		if(dev[devNo]){
			nComediDevices = devNo + 1;
		} else {
			break;
		}
	}

	// none detected
	if (nComediDevices<1) {
		fprintf(stderr,"No comedi devices detected!\n");
		exit(1);
	}

	// create channel lists
	chanlist = new unsigned int*[nComediDevices];
	// create command structures
	cmd = new comedi_cmd*[nComediDevices];
	// find the subdevice which is analogue in
	subdevice = comedi_find_subdevice_by_type(dev[0],COMEDI_SUBD_AI,0);

	// check if user has specified channels or if requested
	// number of channels make sense
	if ((channels_in_use < 1)||
	    (channels_in_use > comedi_get_n_channels(dev[0],subdevice)))
	{
		channels_in_use = comedi_get_n_channels(dev[0],subdevice);
	}

	// create channel lists and the command structures
	for(int devNo=0;devNo<nComediDevices;devNo++) {
		chanlist[devNo] = new unsigned int[channels_in_use];
		assert( chanlist[devNo]!=NULL );
		for(int i=0;i<channels_in_use;i++){
			chanlist[devNo][i] = CR_PACK(i,range,aref);
		}
		cmd[devNo] = new comedi_cmd;
		assert( dev[devNo]!=NULL );
		int r = comedi_get_cmd_generic_timed(dev[devNo],
						     subdevice,
						     cmd[devNo],
						     channels_in_use,
						     (int)(1e9/req_sampling_rate));
		if(r<0){
			comedi_perror("comedi_get_cmd_generic_timed failed\n");
			exit(-1);
		}
		/* Modify parts of the command */
		cmd[devNo]->chanlist           = chanlist[devNo];
		cmd[devNo]->chanlist_len       = channels_in_use;
		cmd[devNo]->scan_end_arg = channels_in_use;
		cmd[devNo]->stop_src=TRIG_NONE;
		cmd[devNo]->stop_arg=0;
		int ret = comedi_command_test(dev[devNo],cmd[devNo]);
		if(ret<0){
			comedi_perror("1st comedi_command_test failed\n");
			exit(-1);
		}
		ret = comedi_command_test(dev[devNo],cmd[devNo]);
		if(ret<0){
			comedi_perror("2nd comedi_command_test failed\n");
			exit(-1);
		}
		if(ret!=0){
			fprintf(stderr,"Error preparing command.\n");
			exit(-1);
		}
	}

	// the timing is done channel by channel
	// this means that the actual sampling rate is divided by
	// number of channels
	if ((cmd[0]->convert_src ==  TRIG_TIMER)&&(cmd[0]->convert_arg)) {
		sampling_rate=((1E9 / cmd[0]->convert_arg)/channels_in_use);
	}
	
	// the timing is done scan by scan (all channels at once)
	// the sampling rate is equivalent of the scan_begin_arg
	if ((cmd[0]->scan_begin_src ==  TRIG_TIMER)&&(cmd[0]->scan_begin_arg)) {
		sampling_rate=1E9 / cmd[0]->scan_begin_arg;
	}

	// initialise the graphics stuff
	ypos = new int**[nComediDevices];
	assert(ypos != NULL);
	for(int devNo=0;devNo<nComediDevices;devNo++) {
		ypos[devNo]=new int*[channels_in_use];
		assert(ypos[devNo] != NULL);
		for(int i=0;i<channels_in_use;i++) {
			ypos[devNo][i] = new int[MAX_DISP_X];
			assert( ypos[devNo][i] != NULL);
			for(int j=0;j<MAX_DISP_X;j++) {
				ypos[devNo][i][j]=0;
			}
		}
	}

	xpos=0;
	nsamples=0;

	maxdata = new lsampl_t[nComediDevices];
	assert( maxdata != NULL );
	crange = new comedi_range*[nComediDevices];
	assert( crange != NULL );
	for(int devNo=0;devNo<nComediDevices;devNo++) {
		// we just go for the default ranges
		maxdata[devNo]=comedi_get_maxdata(dev[devNo],subdevice,0);
		crange[devNo]=comedi_get_range(dev[devNo],subdevice,0,0);
	}

	// 50Hz or 60Hz mains notch filter
	iirnotch = new Iir::Butterworth::BandStop<IIRORDER>**[nComediDevices];
	assert( iirnotch != NULL );
	adAvgBuffer = new float*[nComediDevices];
	assert( adAvgBuffer != NULL );
	daqData = new lsampl_t*[nComediDevices];
	assert( daqData != NULL );
	for(int devNo=0;devNo<nComediDevices;devNo++) {
		iirnotch[devNo] = new Iir::Butterworth::BandStop<IIRORDER>*[channels_in_use];
		assert( iirnotch[devNo] != NULL );
		// floating point buffer for plotting
		adAvgBuffer[devNo]=new float[channels_in_use];
		assert( adAvgBuffer[devNo] != NULL );
		for(int i=0;i<channels_in_use;i++) {
			adAvgBuffer[devNo][i]=0;
			iirnotch[devNo][i] = new Iir::Butterworth::BandStop<IIRORDER>;
			assert( iirnotch[devNo][i] != NULL );
		}
		// raw data buffer for saving the data
		daqData[devNo] = new lsampl_t[channels_in_use];
		assert( daqData[devNo] != NULL );
		for(int i=0;i<channels_in_use;i++) {
			daqData[devNo][i]=0;
		}
	}

	setNotchFrequency(f);

	counter = new QTimer( this );
	assert( counter != NULL );
	connect( counter, 
		 SIGNAL(timeout()),
		 this, 
		 SLOT(updateTime()) );
}
Exemple #19
0
/**
 * @brief Get the information from Comedi library
 *
 */
void MainWindow::GetComediInfo()
    {
    int i,j;
    int n_subdevices,type;
    int chan,n_chans;
    int n_ranges;
    int subdev_flags;
    comedi_range *rng;

    ChannelList.clear();
    // at the moment we are using the default device
    const char optionsfilename[]="/dev/comedi0";
    QString DeviceName=AppSettings.value(Key_Comedi_Device_Name).toString();
    if (DeviceName.length()<=0) DeviceName=optionsfilename;
    it = comedi_open(optionsfilename);
    if(!it)
        {
        QMessageBox::warning(this, optionsfilename,
            tr("Can not open the device\n"),
            QMessageBox::Ok);
        };
    cbComediDevice->addItem(optionsfilename,1);
    AppSettings.setValue(Key_Comedi_Device_Name,DeviceName);

    QString buffer="Overall info:\n";
    //buffer+=QString    printf("  Version code: 0x%06x\n", comedi_get_version_code(it));
    buffer+=QString("  Comedi version code: 0x%06x\n").arg(comedi_get_version_code(it));
    buffer+=QString("  Driver name: %1\n").arg(comedi_get_driver_name(it));
    buffer+=QString("  Board name: %1\n").arg(comedi_get_board_name(it));
    n_subdevices = comedi_get_n_subdevices(it);
    buffer+=QString(" Number of subdevices: %1\n").arg(n_subdevices);

    tlComediInfo->setText(buffer);

    int channel_unique_id=1;


    // Now scan subdevices
    for(i = 0; i < n_subdevices; i++)
        {
        buffer.clear();
        type = comedi_get_subdevice_type(it, i);
        if(type==COMEDI_SUBD_UNUSED) continue;

        QTextEdit * tabText=new QTextEdit;
        buffer+=QString("Subdevice %1\n").arg(i);
        buffer+=QString("Type: %1 (%2)\n").arg(type).arg(subdevice_types[type]);

        subdev_flags = comedi_get_subdevice_flags(it, i);
        QString flagsstring;
        flagsstring.sprintf("flags: 0x%08x\n",subdev_flags);
        buffer+=flagsstring;

        n_chans=comedi_get_n_channels(it,i);
        buffer+=QString("  Number of channels: %1\n").arg(n_chans);
        if ((type==1)||(type==2)) // Analog input or output
            {
            for(chan=0;chan<n_chans;chan++)
                {
                // here!
                ChannelList.append(AIO_channel(QString(optionsfilename),i,chan,0,type==1,++channel_unique_id));
                };
            };


        if(!comedi_maxdata_is_chan_specific(it,i))
            {
            buffer+=QString("  Maximal data value: %1\n").arg((unsigned long)comedi_get_maxdata(it,i,0));
            }
            else
            {
            buffer+=QString("  Maximal data value is channel specific:\n");
            for(chan=0;chan<n_chans;chan++)
                {
                buffer+=QString("    Channel %1: %2\n").arg(chan).arg
                    ((unsigned long)comedi_get_maxdata(it,i,chan));
                }
            };

        buffer+=QString("  ranges:\n");
        if (!comedi_range_is_chan_specific(it,i))
            {
            n_ranges=comedi_get_n_ranges(it,i,0);
            buffer+=QString("    All channels:");
            for(j=0;j<n_ranges;j++)
                {
                rng=comedi_get_range(it,i,0,j);
//                buffer+=QString(" [%g,%g]",rng->min,rng->max);
                buffer+=QString(" [%1,%2]").arg(rng->min).arg(rng->max);
                }
            buffer+=QString("\n");
            }
            else
            {
            for (chan=0;chan<n_chans;chan++)
                {
                n_ranges=comedi_get_n_ranges(it,i,chan);
                printf("    chan%d:",chan);
                for(j=0;j<n_ranges;j++)
                    {
                    rng=comedi_get_range(it,i,chan,j);
                    printf(" [%g,%g]",rng->min,rng->max);
                    }
                printf("\n");
                }

            }
        tabText->setText(buffer);
        tabWidget->addTab(tabText,QString("subdevice %1").arg(i));
        }
        //printf("  command:\n");
        //get_command_stuff(it,i);


    tabWidget->setTabText(0,tr("Connections"));

    // Create channles we might need; all are input channels save one


     Ini_ImI=   new AIO_channel(Key_Im_Input,1);
     Ini_CmdI=  new AIO_channel(Key_Cmd_Input,1);
     Ini_CmI=   new AIO_channel(Key_Cm_Tlgf_Input,1);
     Ini_GainT= new AIO_channel(Key_Gain_Tlgf_Input,1);
     Ini_FreqT= new AIO_channel(Key_Freq_Tlgf_Input,1);
     Ini_LswT=  new AIO_channel(Key_Lsw_Tlgf_Input,1);

     Ini_CmdO=  new AIO_channel(Key_Cmd_Output,0);


     for (int ch=0;ch<ChannelList.count();ch++)
        {
        if (ChannelList[ch].is_input)
            {
            cbxAI_Im->addItem(ChannelList[ch].Description(),ChannelList[ch].ID());
            if (ChannelList[ch]==Ini_ImI)  {
                int zzz=cbxAI_Im->count();
                cbxAI_Im->setCurrentIndex(zzz-1);
                };

            cbxAI_Cmd->addItem(ChannelList[ch].Description(),ChannelList[ch].ID());
            if (ChannelList[ch]==Ini_CmdI) { cbxAI_Cmd->setCurrentIndex(cbxAI_Cmd->count()-1); };

            cbxAI_Cm_tlg->addItem(ChannelList[ch].Description(),ChannelList[ch].ID());
            if (ChannelList[ch]==Ini_CmI)  { cbxAI_Cm_tlg->setCurrentIndex(cbxAI_Cm_tlg->count()-1); };

            cbxAI_Gain_tlg->addItem(ChannelList[ch].Description(),ChannelList[ch].ID());
            if (ChannelList[ch]==Ini_GainT){ cbxAI_Gain_tlg->setCurrentIndex(cbxAI_Gain_tlg->count()-1); };

            cbxAI_Freq_tlg->addItem(ChannelList[ch].Description(),ChannelList[ch].ID());
            if (ChannelList[ch]==Ini_FreqT) { cbxAI_Freq_tlg->setCurrentIndex(cbxAI_Freq_tlg->count()-1); };

            cbxAI_Lsw_tlg->addItem(ChannelList[ch].Description(),ChannelList[ch].ID());
            if (ChannelList[ch]==Ini_LswT) { cbxAI_Lsw_tlg->setCurrentIndex(cbxAI_Lsw_tlg->count()-1); };
            }
            else
            {
            cbxAO_Cmd->addItem(ChannelList[ch].Description(),ChannelList[ch].ID());
            if (ChannelList[ch]==Ini_CmdO)
                {
                cbxAO_Cmd->setCurrentIndex(cbxAO_Cmd->count()-1);
                };
            };

        };
    return;
    }
Exemple #20
0
static PyObject*
comediModule(PyObject* self, PyObject* args)
{
	char *device;
	int subdevice;
	int channel;
	int range;
	int aref;
	int n_chan;
	int n_scan;
	float freq;
    if (!PyArg_ParseTuple(args, "siiiiiif", &device, &subdevice, &channel, &range, &aref, &n_chan, &n_scan, &freq))
        return NULL;
    
	comedi_t *dev;
	comedi_cmd c,*cmd=&c;
	int ret;
	int total=0;
	int i;
	struct timeval start,end;
	int subdev_flags;
	lsampl_t raw;
	struct parsed_options options;

	init_parsed_options(&options);
	options.filename = device;
	options.subdevice = subdevice;
	options.channel = channel;
	options.range = range;
	options.aref = aref;
	options.n_chan = n_chan;
	options.n_scan = n_scan;
	options.freq = freq;

	/* open the device */
	dev = comedi_open(options.filename);
	if(!dev){
		comedi_perror(options.filename);
		exit(1);
	}

	// Print numbers for clipped inputs
	comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);

	/* Set up channel list */
	for(i = 0; i < options.n_chan; i++){
		chanlist[i] = CR_PACK(options.channel + i, options.range, options.aref);
		range_info[i] = comedi_get_range(dev, options.subdevice, options.channel, options.range);
		maxdata[i] = comedi_get_maxdata(dev, options.subdevice, options.channel);
	}
	prepare_cmd_lib(dev, options.subdevice, options.n_scan, options.n_chan, 1e9 / options.freq, cmd);

	fprintf(stderr, "command before testing:\n");
	dump_cmd(stderr, cmd);

	ret = comedi_command_test(dev, cmd);
	if(ret < 0){
		comedi_perror("comedi_command_test");
		if(errno == EIO){
			fprintf(stderr,"Ummm... this subdevice doesn't support commands\n");
		}
		exit(1);
	}
	fprintf(stderr,"first test returned %d (%s)\n", ret,
			cmdtest_messages[ret]);
	dump_cmd(stderr, cmd);

	ret = comedi_command_test(dev, cmd);
	if(ret < 0){
		comedi_perror("comedi_command_test");
		exit(1);
	}
	fprintf(stderr,"second test returned %d (%s)\n", ret,
			cmdtest_messages[ret]);
	if(ret!=0){
		dump_cmd(stderr, cmd);
		fprintf(stderr, "Error preparing command\n");
		exit(1);
	}

	/* this is only for informational purposes */
	gettimeofday(&start, NULL);
	fprintf(stderr,"start time: %ld.%06ld\n", start.tv_sec, start.tv_usec);

	/* start the command */
	ret = comedi_command(dev, cmd);
	if(ret < 0){
		comedi_perror("comedi_command");
		exit(1);
	}
	subdev_flags = comedi_get_subdevice_flags(dev, options.subdevice);

	const int ndim = 2;
	npy_intp nd[2] = {n_scan, n_chan};
	
	PyObject *myarray;
	double *array_buffer;
	myarray = PyArray_SimpleNew(ndim, nd, NPY_DOUBLE);
	Py_INCREF(myarray);
	array_buffer = (double *)PyArray_DATA(myarray);
	
	while(1){
		ret = read(comedi_fileno(dev),buf,BUFSZ);
		if(ret < 0){
			/* some error occurred */
			perror("read");
			break;
		}else if(ret == 0){
			/* reached stop condition */
			break;
		}else{
			static int col = 0;
			double j = 0.0;
			
			int bytes_per_sample;
			total += ret;
			if(options.verbose)fprintf(stderr, "read %d %d\n", ret, total);
			if(subdev_flags & SDF_LSAMPL)
				bytes_per_sample = sizeof(lsampl_t);
			else
				bytes_per_sample = sizeof(sampl_t);
			for(i = 0; i < ret / bytes_per_sample; i++){
				if(subdev_flags & SDF_LSAMPL) {
					raw = ((lsampl_t *)buf)[i];
				} else {
					raw = ((sampl_t *)buf)[i];
				}
				*array_buffer++ = print_datum(raw, col, 1);
				col++;
				if(col == options.n_chan){
					col=0;
					j++;
					printf("\n");
				}
			}
		}
	}

	/* this is only for informational purposes */
	gettimeofday(&end,NULL);
	fprintf(stderr,"end time: %ld.%06ld\n", end.tv_sec, end.tv_usec);

	end.tv_sec -= start.tv_sec;
	if(end.tv_usec < start.tv_usec){
		end.tv_sec--;
		end.tv_usec += 1000000;
	}
	end.tv_usec -= start.tv_usec;
	fprintf(stderr,"time: %ld.%06ld\n", end.tv_sec, end.tv_usec);
    
	return myarray;
}
MainWindow::MainWindow( QWidget *parent ) :
    QWidget(parent),
    adChannel(0),
    psthLength(1000),
    psthBinw(20),
    spikeThres(1),
    psthOn(0),
    spikeDetected(false),
    time(0),
    linearAverage(0)
{
  // initialize comedi
  const char *filename = "/dev/comedi0";

  /* open the device */
  if( (dev = comedi_open(filename)) == 0 )
  {
    comedi_perror(filename);
    exit(1);
  }

  // do not produce NAN for out of range behaviour
  comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER); 

  maxdata = comedi_get_maxdata(dev, COMEDI_SUB_DEVICE, 0);
  crange = comedi_get_range(dev,COMEDI_SUB_DEVICE,0,0);
  numChannels = comedi_get_n_channels(dev, COMEDI_SUB_DEVICE);

  chanlist = new unsigned[numChannels];

  /* Set up channel list */
  for( int i=0; i<numChannels; i++ )
    chanlist[i] = CR_PACK(i, COMEDI_RANGE_ID, AREF_GROUND);

  int ret = comedi_get_cmd_generic_timed( dev,
                                          COMEDI_SUB_DEVICE,
                                          &comediCommand,
                                          numChannels,
                                          (int)(1e9/(SAMPLING_RATE)) );

  if(ret < 0)
  {
    printf("comedi_get_cmd_generic_timed failed\n");
    exit(-1);
  }

  /* Modify parts of the command */
  comediCommand.chanlist = chanlist;
  comediCommand.stop_src = TRIG_NONE;
  comediCommand.stop_arg = 0;

  /* comedi_command_test() tests a command to see if the
   * trigger sources and arguments are valid for the subdevice.
   * If a trigger source is invalid, it will be logically ANDed
   * with valid values (trigger sources are actually bitmasks),
   * which may or may not result in a valid trigger source.
   * If an argument is invalid, it will be adjusted to the
   * nearest valid value.  In this way, for many commands, you
   * can test it multiple times until it passes.  Typically,
   * if you can't get a valid command in two tests, the original
   * command wasn't specified very well. */
  ret = comedi_command_test(dev, &comediCommand);

  if(ret < 0)
  {
    comedi_perror("comedi_command_test");
    exit(-1);
  }

  fprintf(stderr, "first test returned %d\n", ret);

  ret = comedi_command_test(dev, &comediCommand);
  if(ret < 0)
  {
    comedi_perror("comedi_command_test");
    exit(-1);
  }

  fprintf(stderr, "second test returned %d\n", ret);

  if(ret != 0)
  {
    fprintf(stderr,"Error preparing command\n");
    exit(-1);
  }

  // the timing is done channel by channel
  // this means that the actual sampling rate is divided by
  // number of channels
  if ((comediCommand.convert_src ==  TRIG_TIMER)&&(comediCommand.convert_arg)) {
	  sampling_rate=(((double)1E9 / comediCommand.convert_arg)/numChannels);
  }
  
  // the timing is done scan by scan (all channels at once)
  // the sampling rate is equivalent of the scan_begin_arg
  if ((comediCommand.scan_begin_src ==  TRIG_TIMER)&&(comediCommand.scan_begin_arg)) {
	  sampling_rate=(double)1E9 / comediCommand.scan_begin_arg;
  }

  // 50Hz or 60Hz mains notch filter
  iirnotch = new Iir::Butterworth::BandStop<IIRORDER>;
  assert( iirnotch != NULL );
  iirnotch->setup (IIRORDER, sampling_rate, NOTCH_F, NOTCH_F/10.0);

  /* start the command */
  ret = comedi_command(dev, &comediCommand);
  if(ret < 0)
  {
    comedi_perror("comedi_command");
    exit(1);
  }

  int subdev_flags = comedi_get_subdevice_flags(dev, COMEDI_SUB_DEVICE);

  if( (sigmaBoard = subdev_flags & SDF_LSAMPL) )
    readSize = sizeof(lsampl_t) * numChannels;
  else
    readSize = sizeof(sampl_t) * numChannels;

  //  Initialize data for plots
  for(int i=0; i<MAX_PSTH_LENGTH; i++)
  {
    xData[i] = i;     // time axis
    yData[i] = 0;
    timeData[i] = double(i)*psthBinw; // psth time axis
    spikeCountData[i] = 0;
    psthData[i] = 0;
  }

  // the gui, straight forward QT/Qwt
  resize(640,420);
  QHBoxLayout *mainLayout = new QHBoxLayout( this );

  QVBoxLayout *controlLayout = new QVBoxLayout;
  mainLayout->addLayout(controlLayout);

  QVBoxLayout *plotLayout = new QVBoxLayout;
  plotLayout->addStrut(400);
  mainLayout->addLayout(plotLayout);

  // two plots
  RawDataPlot = new DataPlot(xData, yData, psthLength, 
			     crange->max, crange->min, this);
  plotLayout->addWidget(RawDataPlot);
  RawDataPlot->show();

  plotLayout->addSpacing(20);

  MyPsthPlot = new PsthPlot(timeData, psthData, psthLength/psthBinw, this);
  plotLayout->addWidget(MyPsthPlot);
  MyPsthPlot->show();

  /*---- Buttons ----*/

  // AD group
  QGroupBox   *ADcounterGroup = new QGroupBox( "A/D Channel", this );
  QVBoxLayout *ADcounterLayout = new QVBoxLayout;

  ADcounterGroup->setLayout(ADcounterLayout);
  ADcounterGroup->setAlignment(Qt::AlignJustify);
  ADcounterGroup->setSizePolicy( QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) );
  controlLayout->addWidget( ADcounterGroup );

  QwtCounter *cntChannel = new QwtCounter(ADcounterGroup);
  cntChannel->setRange(0, numChannels-1, 1);
  cntChannel->setValue(adChannel);
  ADcounterLayout->addWidget(cntChannel);
  connect(cntChannel, SIGNAL(valueChanged(double)), SLOT(slotSetChannel(double)));

  filter50HzCheckBox = new QCheckBox( "50Hz filter" );
  filter50HzCheckBox->setEnabled( true );
  ADcounterLayout->addWidget(filter50HzCheckBox);

  // psth functions
  QGroupBox   *PSTHfunGroup  = new QGroupBox( "Actions", this );
  QVBoxLayout *PSTHfunLayout = new QVBoxLayout;

  PSTHfunGroup->setLayout(PSTHfunLayout);
  PSTHfunGroup->setAlignment(Qt::AlignJustify);
  PSTHfunGroup->setSizePolicy( QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) );
  controlLayout->addWidget( PSTHfunGroup );

  averagePsth = new QComboBox(PSTHfunGroup);
  averagePsth->addItem(tr("PSTH"));
  averagePsth->addItem(tr("VEP"));
  PSTHfunLayout->addWidget(averagePsth);
  connect( averagePsth, SIGNAL(currentIndexChanged(int)), SLOT(slotAveragePsth(int)) );

  triggerPsth = new QPushButton(PSTHfunGroup);
  triggerPsth->setText("PSTH on");
  triggerPsth->setCheckable(true);
  PSTHfunLayout->addWidget(triggerPsth);
  connect(triggerPsth, SIGNAL(clicked()), SLOT(slotTriggerPsth()));

  QPushButton *clearPsth = new QPushButton(PSTHfunGroup);
  clearPsth->setText("clear data");
  PSTHfunLayout->addWidget(clearPsth);
  connect(clearPsth, SIGNAL(clicked()), SLOT(slotClearPsth()));

  QPushButton *savePsth = new QPushButton(PSTHfunGroup);
  savePsth->setText("save data");
  PSTHfunLayout->addWidget(savePsth);
  connect(savePsth, SIGNAL(clicked()), SLOT(slotSavePsth()));

  // psth params
  QGroupBox   *PSTHcounterGroup = new QGroupBox( "Parameters", this );
  QVBoxLayout *PSTHcounterLayout = new QVBoxLayout;

  PSTHcounterGroup->setLayout(PSTHcounterLayout);
  PSTHcounterGroup->setAlignment(Qt::AlignJustify);
  PSTHcounterGroup->setSizePolicy( QSizePolicy(QSizePolicy::Fixed,
					       QSizePolicy::Fixed) );
  controlLayout->addWidget( PSTHcounterGroup );

  QLabel *psthLengthLabel = new QLabel("Sweep length", PSTHcounterGroup);
  PSTHcounterLayout->addWidget(psthLengthLabel);

  QwtCounter *cntSLength = new QwtCounter(PSTHcounterGroup);
  cntSLength->setNumButtons(2);
  cntSLength->setIncSteps(QwtCounter::Button1, 10);
  cntSLength->setIncSteps(QwtCounter::Button2, 100);
  cntSLength->setRange(1, MAX_PSTH_LENGTH, 1);
  cntSLength->setValue(psthLength);
  PSTHcounterLayout->addWidget(cntSLength);
  connect(cntSLength, 
	  SIGNAL(valueChanged(double)), 
	  SLOT(slotSetPsthLength(double)));

  QLabel *binwidthLabel = new QLabel("Binwidth", PSTHcounterGroup);
  PSTHcounterLayout->addWidget(binwidthLabel);

  cntBinw = new QwtCounter(PSTHcounterGroup);
  cntBinw->setNumButtons(2);
  cntBinw->setIncSteps(QwtCounter::Button1, 1);
  cntBinw->setIncSteps(QwtCounter::Button2, 10);
  cntBinw->setRange(1, 100, 1);
  cntBinw->setValue(psthBinw);
  PSTHcounterLayout->addWidget(cntBinw);
  connect(cntBinw, SIGNAL(valueChanged(double)), SLOT(slotSetPsthBinw(double)));

  QLabel *thresholdLabel = new QLabel("Spike Threshold", PSTHcounterGroup);
  PSTHcounterLayout->addWidget(thresholdLabel);

  editSpikeT = new QTextEdit("0");
  QFont editFont("Courier",14);
  QFontMetrics editMetrics(editFont);
  editSpikeT->setMaximumHeight ( editMetrics.height()*1.2 );
  editSpikeT->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  editSpikeT->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  editSpikeT->setFont(editFont);
  PSTHcounterLayout->addWidget(editSpikeT);
  connect(editSpikeT, SIGNAL(textChanged()), SLOT(slotSetSpikeThres()));

  thresholdMarker = new QwtPlotMarker();
  thresholdMarker->setValue(0,0);
  thresholdMarker->attach(RawDataPlot);
  thresholdMarker->setLineStyle(QwtPlotMarker::HLine);

  // Generate timer event every 50ms
  (void)startTimer(50);

}
Exemple #22
0
static int configBoard( int board ) {
    MY_BOARD_HARDWARE *pBoardHard = myBoard_getHardwareBoard( board );
    MY_BOARD_SOFTWARE *pBoardSoft = myBoard_getSoftwareBoard( board );

    if (pBoardHard == NULL || pBoardSoft == NULL) return -1;

    comedi_insn insn;
    lsampl_t p_insn_data[3];
    int i;
    int status;

    insn.insn = INSN_CONFIG;
    insn.data = p_insn_data;
    insn.subdev = pBoardHard->subDeviceNumber;
    insn.n = 2;
    insn.data[0] = INSN_CONFIG_BLOCK_SIZE;
    insn.data[1] = 256;
    for(i=0; i < pBoardSoft->numberOfActiveAnalogInputs; i++){
        int indexRange = pBoardHard->channelIndexRange[i];

        insn.chanspec=CR_PACK(
            i,
            indexRange,
            pBoardHard->analogReference
        );
        status = comedi_do_insn(
            pBoardHard->p_comediFileHandle,
            &insn
        );
        if (status<0) {
            fprintf( stderr, "failed do inst for board[%d]\n", board );
            return -1;
        } 
    }

    if (pBoardHard->maxDataIsChannelSpecific ||
    pBoardHard->rangeIsChannelSpecific) {
        for(i=0; i < pBoardSoft->numberOfActiveAnalogInputs; i++){
            const comedi_range *pVoltageRange = comedi_get_range(
                pBoardHard->p_comediFileHandle,
                pBoardHard->subDeviceNumber,
                i,
                pBoardHard->channelIndexRange[i]
            );
            int rawMax = comedi_get_maxdata(
                pBoardHard->p_comediFileHandle,
                pBoardHard->subDeviceNumber,
                i
            );
            pBoardHard->channelRawToVoltA[i] = (pVoltageRange->max - pVoltageRange->min) / rawMax;
            pBoardHard->channelRawToVoltB[i] = pVoltageRange->min;
            fprintf( stderr, "set convert CONST for board[%d] channel[%d] a=%lf b=%lf\n",
                board, i,
                pBoardHard->channelRawToVoltA[i],
                pBoardHard->channelRawToVoltB[i]
            );
        }/* for channel */
    } else {
        const comedi_range *pVoltageRange = comedi_get_range(
            pBoardHard->p_comediFileHandle,
            pBoardHard->subDeviceNumber,
            0,
            pBoardHard->channelIndexRange[0]
        );
        int rawMax = comedi_get_maxdata(
            pBoardHard->p_comediFileHandle,
            pBoardHard->subDeviceNumber,
            0
        );
        double rawToVoltA = (pVoltageRange->max - pVoltageRange->min) / rawMax;
        double rawToVoltB = pVoltageRange->min;
        fprintf( stderr, "set convert CONST for all channel on board[%d] a=%lf b=%lf\n", board,
            rawToVoltA,
            rawToVoltB
        );
        for(i=0; i < pBoardSoft->numberOfActiveAnalogInputs; i++){
            pBoardHard->channelRawToVoltA[i] = rawToVoltA;
            pBoardHard->channelRawToVoltB[i] = rawToVoltB;
        }
    }

    return 0;
}
Exemple #23
0
bogio_spec *bogio_open(bogio_spec *spec)
{
    unsigned int *chanlist;       /* For Comedi channel flags */
    unsigned int osr;             /* Oversampling rate */
    int i;
    
    /* Maybe the caller didn't have a bogio_spec */
    if (spec == NULL) {
        spec            = calloc(1U, sizeof(bogio_spec));
        /* We have to set these here because 0 is a valid argument */
        spec->subdevice = 0U;
        spec->range     = 0U; /* +/- 4V */
        spec->aref      = AREF_GROUND;
    }
    
    /* Set defaults if the caller didn't supply parameters */
    if (spec->comedi_device == NULL)
        spec->comedi_device = "/dev/comedi0";
    if (spec->sample_rate == 0)
        spec->sample_rate = 1000; /* 1kHz default sample rate */
    if (spec->channels == 0)
        spec->channels = 8;       /* 8 input channels by default */
    /* implied: oversampling = 0 (no oversampling) */
    
    /* Reserve memory for the Comedi command */
    spec->m_cmd = calloc(1, sizeof(comedi_cmd));
    
    /* Try to open the device */
    spec->m_dev = comedi_open(spec->comedi_device);
    if (spec->m_dev == NULL){
        comedi_perror(spec->comedi_device);
        return NULL;
    }
    
    /* Calculate the oversampled rate for the target sample rate */
    spec->oversampling = 0; /* To do! */
    osr = spec->oversampling ? spec->oversampling : 1;
    osr *= (1000000000U/spec->sample_rate);   /* That's 1e9 */
    
    /* Set up channel list */
    chanlist = (unsigned int *)calloc(spec->channels, sizeof(unsigned int));
    for(i=0 ; i < spec->channels ; i++)
        chanlist[i]=CR_PACK(i, spec->range, spec->aref);
    
    i = comedi_get_cmd_generic_timed(spec->m_dev,
                                     spec->subdevice,
                                     spec->m_cmd,
                                     spec->channels,
                                     osr
                                    );
    if (i < 0) {
        fprintf(stderr, "comedi_get_cmd_generic_timed failed\n");
        return NULL;
    }
    
    /* Modify parts of the command */
    spec->m_cmd->chanlist     = chanlist;
    spec->m_cmd->chanlist_len = spec->channels;
    spec->m_cmd->scan_end_arg = spec->channels;
    spec->m_cmd->stop_src     = TRIG_NONE;
    spec->m_cmd->stop_arg     = 0;

    /* comedi_command_test() tests a command to see if the
       trigger sources and arguments are valid for the subdevice.
       If a trigger source is invalid, it will be logically ANDed
       with valid values (trigger sources are actually bitmasks),
       which may or may not result in a valid trigger source.
       If an argument is invalid, it will be adjusted to the
       nearest valid value.  In this way, for many commands, you
       can test it multiple times until it passes.  Typically,
       if you can't get a valid command in two tests, the original
       command wasn't specified very well. */
    i = comedi_command_test(spec->m_dev, spec->m_cmd);
    if (i < 0) {
        comedi_perror("comedi_command_test -- first attempt");
        exit(-1);
    }
    /* fprintf(stderr,"first test returned %d\n",i); */

    i = comedi_command_test(spec->m_dev, spec->m_cmd);
    if (i < 0){
        comedi_perror("comedi_command_test -- second attempt");
        return NULL;
    }
    /* fprintf(stderr,"second test returned %d\n",i); */
    
    if (i != 0){
        fprintf(stderr,"Error preparing command\n");
        return NULL;
    }
    
    /* Make sure the sample rate wasn't modified */
    if (spec->m_cmd->convert_src==TRIG_TIMER && spec->m_cmd->convert_arg)
        spec->sample_rate = 1E9/spec->m_cmd->convert_arg;

    if (spec->m_cmd->scan_begin_src==TRIG_TIMER && spec->m_cmd->scan_begin_arg)
        spec->sample_rate = 1E9/spec->m_cmd->scan_begin_arg;

    /* start the command */
    i = comedi_command(spec->m_dev, spec->m_cmd);
    if (i < 0) {
        comedi_perror("comedi_command");
        return NULL;
    }
    
    /* That worked: report the current settings */
    /* Read the maxdata value and range for each channel;
       it will be used later for normalisation */
    spec->m_max_sample = calloc(spec->channels, sizeof(lsampl_t));
    spec->fsd = calloc(spec->channels, sizeof(comedi_range *));
    for (i = 0 ; i < spec->channels ; i++) {
        spec->m_max_sample[i] = comedi_get_maxdata(spec->m_dev,
                                                   spec->subdevice,
                                                   i);
        spec->fsd[i]          = comedi_get_range(spec->m_dev,
                                                 spec->subdevice,
                                                 i,
                                                 spec->range);
    }

    return spec;
}
Exemple #24
0
static long dsetInit_devDoSyncComedi (boRecord *pbo)
{
  CONTEXT *p_myContext;
  comediSupport *p_myBinaryOutput;
   

  #ifdef DEBUG1
  packageInfo(); 
  printf( __FILE__ "[%d] -> %s \n", __LINE__, __func__ );
  #endif

  #ifdef DEBUG2
  printf( __FILE__ "[%d] Initializing %s\n", __LINE__, pbo->name);
  #endif

  p_myBinaryOutput=(comediSupport *)calloc(1,sizeof(comediSupport));

				/* Get the options from the db file	*/
  sscanf(pbo->out.value.instio.string,
		"d=%s s=%d c=%d",
		p_myBinaryOutput->filename,
		&p_myBinaryOutput->subdevice,
		&p_myBinaryOutput->channel);

  #ifdef DEBUG2
  printf(__FILE__ "[%d] Parsed options >%s<\n", 
		__LINE__, pbo->out.value.instio.string);
  printf(__FILE__ "[%d]   filename  = >%s<\n", 
		__LINE__, p_myBinaryOutput->filename);
  printf(__FILE__ "[%d]   subdevice = %d\n", 
		__LINE__, p_myBinaryOutput->subdevice);
  printf(__FILE__ "[%d]   channel   = %d\n", 
		__LINE__, p_myBinaryOutput->channel);
  #endif

  p_myBinaryOutput->device=comedi_open(p_myBinaryOutput->filename);

  p_myBinaryOutput->maxdata=comedi_get_maxdata( 	p_myBinaryOutput->device,
						p_myBinaryOutput->subdevice,
						p_myBinaryOutput->channel);
/*
p_myBinaryOutput->c_range=comedi_get_range(	p_myBinaryOutput->device,
						p_myBinaryOutput->subdevice,
						p_myBinaryOutput->channel,
						p_myBinaryOutput->range);
*/


  if (initComediDO(p_myBinaryOutput) <= ERROR ) {
	printf(__FILE__ "[%d] Error: Couldn't intialize %s\n",
			__LINE__, pbo->name);
        sleep(SLEEPTIME_ERROR);
	return(ERROR);
  }


				/* Save the context */
  p_myContext=(CONTEXT *)calloc(1,sizeof(CONTEXT));
  p_myContext->p_binaryOutput=p_myBinaryOutput;
  #ifdef WARMSTART
  p_myContext->operatingMode=WARMSTART_MODE;
  pbo->pini=menuYesNoYES;
  #endif
  pbo->dpvt=(void *)p_myContext;

  #ifdef DEBUG1
  printf( __FILE__ "[%d] <- %s\n", __LINE__, __func__ );
  #endif

  return(SUCCESS);
}
Exemple #25
0
int main(int argc, char *argv[])
{
  comedi_cmd cmd;
  int err;
  int n, m, k;
  comedi_t *dev;
  unsigned int chanlist[100];
  unsigned int maxdata;
  comedi_range *rng;
  int ret;
  struct parsed_options options;
  int fn = 256*256;
  sampl_t *data, *dp;
  float v;

  init_parsed_options(&options);
  options.subdevice = -1;
  options.n_chan = 100000;/* default number of samples */
  parse_options(&options, argc, argv);

  dev = comedi_open( options.filename );
  if(dev == NULL){
    fprintf(stderr, "error opening %s\n", options.filename);
    return -1;
  }
  if(options.subdevice < 0)
    options.subdevice = comedi_find_subdevice_by_type(dev, COMEDI_SUBD_AI, 0);

  maxdata = comedi_get_maxdata(dev, options.subdevice, options.channel);
  rng = comedi_get_range(dev, options.subdevice, options.channel, options.range);

  memset(&cmd,0,sizeof(cmd));
  /*
  cmd.subdev = options.subdevice;
  cmd.flags = 0;
  cmd.start_src = TRIG_INT;
  cmd.start_arg = 0;
  cmd.scan_begin_src = TRIG_TIMER;
  cmd.scan_begin_arg = 1e9 / options.freq;
  cmd.convert_src = TRIG_TIMER;
  cmd.convert_arg = 1e9 / options.freq / 50;
  cmd.scan_end_src = TRIG_COUNT;
  cmd.scan_end_arg = options.n_chan;
  cmd.stop_src = TRIG_COUNT;
  cmd.stop_arg = fn;
  cmd.stop_src = TRIG_NONE;
  cmd.stop_arg = 0;
  */

  cmd.scan_begin_src = TRIG_TIMER;
  cmd.flags = TRIG_ROUND_NEAREST;
  err = comedi_get_cmd_generic_timed( dev, options.subdevice,
				      &cmd, options.n_chan,
				      1e9 / options.freq );
  cmd.start_src = TRIG_INT;
  cmd.start_arg = 0;
  cmd.scan_end_arg = options.n_chan;
  cmd.stop_src = TRIG_NONE;
  cmd.stop_arg = 0;
  
  cmd.chanlist = chanlist;
  cmd.chanlist_len = options.n_chan;

  for ( k=0; k<options.n_chan; k++ )
    chanlist[k] = CR_PACK(k, options.range, options.aref);

  dump_cmd(stderr,&cmd);

  if ( cmd.scan_begin_arg > 1e9 / options.freq ) {
    fprintf( stderr, "frequency too high! Maximum possible is %g Hz\n", 1.0e9/cmd.scan_begin_arg );
    comedi_close( dev );
    return 1;
  }

  err = comedi_command_test(dev, &cmd);
  if (err > 0 && err != 4 ) {
    fprintf( stderr, "comedi_command_test returned %d\n", err );
    dump_cmd(stdout,&cmd);
    exit(1);
  }
  
  err = comedi_command_test(dev, &cmd);
  if (err > 0 && err != 4 ) {
    fprintf( stderr, "comedi_command_test returned %d\n", err );
    dump_cmd(stdout,&cmd);
    exit(1);
  }

  dump_cmd(stderr,&cmd);

  /* init data buffer: */
  data = (sampl_t *)malloc( fn*sizeof( sampl_t ) );
  if(data == NULL ){
    perror("malloc\n");
    exit(1);
  }
  
  fprintf( stderr, "execute command ...\n" );
  if ((err = comedi_command(dev, &cmd)) < 0) {
    comedi_perror("comedi_command");
    exit(1);
  }
  
  fprintf( stderr, "start analog input ...\n" );
  ret = comedi_internal_trigger(dev, options.subdevice, 0);
  if(ret < 0){
    perror("comedi_internal_trigger\n");
    exit(1);
  }
  
  n = 0;
  while( 1 ) {
    m = read(comedi_fileno(dev),(void *)data,fn*sizeof( sampl_t));
    if(m<0){
      if ( errno != EAGAIN ) {
	perror("read");
	exit(0);
      }
      else {
	fprintf( stderr, "... no more data can be read! Try later.\n" );
	usleep( 100000 );
      }
    }
    else {
      m /= sizeof( sampl_t);
      fprintf( stderr, "read %d samples\n",m);
      n+=m;
    }
  }
  comedi_cancel( dev, cmd.subdev );

  fprintf( stderr, "finished\n" );

  /* save data: */

  dp = data;  
  for ( k=0; k<n; k++ ) {
    v = comedi_to_phys(*dp, rng, maxdata);
    printf( "%g\n", v );
    /*    printf( "%d\n", *dp );*/
    ++dp;
  }

  free( data );

  comedi_close( dev );
  
  return 0;
}
Exemple #26
0
int main(int argc, char *argv[])
{
	comedi_t *dev;
	comedi_cmd c,*cmd=&c;
	int ret;
	int total=0;
	int i;
	struct timeval start,end;
	int subdev_flags;
	lsampl_t raw;
	struct parsed_options options;

	init_parsed_options(&options);
	parse_options(&options, argc, argv);

	/* The following variables used in this demo
	 * can be modified by command line
	 * options.  When modifying this demo, you may want to
	 * change them here. */
	options.filename = "/dev/comedi0";
	options.subdevice = 0;
	options.channel = 0;
	options.range = 6;  
	options.aref = AREF_DIFF;
	options.n_chan = 8;
	options.n_scan = 100000;
	options.freq = 1000.0;
	options.physical = 1;

	/* open the device */
	dev = comedi_open(options.filename);
	if(!dev){
		comedi_perror(options.filename);
		exit(1);
	}

	// Print numbers for clipped inputs
	comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);

	/* Set up channel list */
	//for(i = 0; i < options.n_chan/2; i++){
	for(i = 0; i < options.n_chan; i++){	
		chanlist[i] = CR_PACK(options.channel + i, options.range, options.aref);
		range_info[i] = comedi_get_range(dev, options.subdevice, options.channel, options.range);
		maxdata[i] = comedi_get_maxdata(dev, options.subdevice, options.channel);
	}

/*
    for(i = options.n_chan/2; i < options.n_chan; i++){
        fprintf(stderr,"%d: %d\n", i, options.channel + i + 8);
        chanlist[i] = CR_PACK(options.channel + i + 8, options.range, options.aref);
        range_info[i] = comedi_get_range(dev, options.subdevice, options.channel, options.range);
        maxdata[i] = comedi_get_maxdata(dev, options.subdevice, options.channel);
    }    
*/

	/* prepare_cmd_lib() uses a Comedilib routine to find a
	 * good command for the device.  prepare_cmd() explicitly
	 * creates a command, which may not work for your device. */
	prepare_cmd_lib(dev, options.subdevice, options.n_scan, options.n_chan, 1e9 / options.freq, cmd);
	//prepare_cmd(dev, options.subdevice, options.n_scan, options.n_chan, 1e9 / options.freq, cmd);

	fprintf(stderr, "command:\n");
	dump_cmd(stderr, cmd);

	/* this is only for informational purposes */
	gettimeofday(&start, NULL);
	fprintf(stderr,"start time: %ld.%06ld\n", start.tv_sec, start.tv_usec);

	/* start the command */
	ret = comedi_command(dev, cmd);
	if(ret < 0){
		comedi_perror("comedi_command");
		exit(1);
	}
	subdev_flags = comedi_get_subdevice_flags(dev, options.subdevice);
	while(1){
		ret = read(comedi_fileno(dev),buf,BUFSZ);
		if(ret < 0){
			/* some error occurred */
			perror("read");
			continue;
		}else if(ret == 0){
			/* reached stop condition */
			break;
		}else{
			static int col = 0;
			int bytes_per_sample;
			total += ret;
			if(options.verbose)fprintf(stderr, "read %d %d\n", ret, total);
			if(subdev_flags & SDF_LSAMPL)
				bytes_per_sample = sizeof(lsampl_t);
			else
				bytes_per_sample = sizeof(sampl_t);
			for(i = 0; i < ret / bytes_per_sample; i++){
				if(subdev_flags & SDF_LSAMPL) {
					raw = ((lsampl_t *)buf)[i];
				} else {
					raw = ((sampl_t *)buf)[i];
				}
				print_datum(raw, col, options.physical);
				col++;
				if(col == options.n_chan){
					printf("\n");
					col=0;
				}
			}
		}
	}

	/* this is only for informational purposes */
	gettimeofday(&end,NULL);
	fprintf(stderr,"end time: %ld.%06ld\n", end.tv_sec, end.tv_usec);

	end.tv_sec -= start.tv_sec;
	if(end.tv_usec < start.tv_usec){
		end.tv_sec--;
		end.tv_usec += 1000000;
	}
	end.tv_usec -= start.tv_usec;
	fprintf(stderr,"time: %ld.%06ld\n", end.tv_sec, end.tv_usec);

	return 0;
}
Exemple #27
0
int PLLReferenceGeneration()
 {
    //Initial test function to try out Real time stuff.
    int m, i=0, err, n;
    lsampl_t data_to_card;
    static comedi_t * dev;
    static int OutputFIFOBufferSize;
    static int PLLGenerationBufferSize;
	unsigned int maxdata;
	unsigned int chanlist[16];
	int ret;
    static lsampl_t data[PLLGenerationBufferNPoints]; //this is the buffer used to send data points out
    comedi_cmd cmd;

    dev = comedi_open(device_names[PLLReferenceGenerationChannel.board_number]);

    //Check the size of the output buffer
    OutputFIFOBufferSize = comedi_get_buffer_size(dev, PLLReferenceGenerationChannel.subdevice);
    rt_printk("OutputFIFO Buffer size is %i\n", OutputFIFOBufferSize);

    //Set the actual buffer size that we will be using to half this and the number of data points to one fourth
    //Now configure the output channel using a Comedi instruction
    //BufferSize is initially set to be double the number of PLLGenerationBufferNPoints
    PLLGenerationBufferSize = 2*PLLGenerationBufferNPoints;


	maxdata = comedi_get_maxdata(dev, PLLReferenceGenerationChannel.subdevice, PLLReferenceGenerationChannel.channel);
	rt_printk("PLL Reference channel max data is %i\n", maxdata);

	offset = maxdata / 2;
	amplitude = maxdata - offset;

	memset(&cmd,0,sizeof(cmd));
	cmd.subdev = PLLReferenceGenerationChannel.subdevice;
	cmd.flags = CMDF_WRITE;
	cmd.start_src = TRIG_INT;
	cmd.start_arg = 0;
	cmd.scan_begin_src = TRIG_TIMER;
	cmd.scan_begin_arg = PLLGenMinPulseTime;  //minimum update time for the
	cmd.convert_src = TRIG_NOW;
	cmd.convert_arg = 0;
	cmd.scan_end_src = TRIG_COUNT;
	cmd.scan_end_arg = NCHAN; //only one channel
	cmd.stop_src = TRIG_NONE;
	cmd.stop_arg = 0;

	cmd.chanlist = chanlist;
	cmd.chanlist_len = NCHAN;

	chanlist[0] = CR_PACK(PLLReferenceGenerationChannel.channel, AO_RANGE, AREF_GROUND);

	dds_init(PLLWaveformFrequency, PLLUpdateFrequency);

	err = comedi_command_test(dev, &cmd);
	if (err < 0) {
		comedi_perror("comedi_command_test");
		exit(1);
	}

	err = comedi_command_test(dev, &cmd);
	if (err < 0) {
		comedi_perror("comedi_command_test");
		exit(1);
	}

	if ((err = comedi_command(dev, &cmd)) < 0) {
		comedi_perror("comedi_command");
		exit(1);
	}

	dds_output(data,PLLGenerationBufferNPoints);
	n = PLLGenerationBufferNPoints * sizeof(sampl_t);
	m = write(comedi_fileno(dev), (void *)data, n);
	if(m < 0){
		perror("write");
		exit(1);
	}else if(m < n)
	{
		fprintf(stderr, "failed to preload output buffer with %i bytes, is it too small?\n"
			"See the --write-buffer option of comedi_config\n", n);
		exit(1);
	}

    if(!(PLLRefGen_Task = rt_task_init_schmod(nam2num( "PLLReferenceGeneration" ), // Name
                                        2, // Priority
                                        0, // Stack Size
                                        0, //, // max_msg_size
                                        SCHED_FIFO, // Policy
                                        CPUMAP ))) // cpus_allowed
        {
            printf("ERROR: Cannot initialize pll reference generation task\n");
            exit(1);
        }

    //specify that this is to run on one CPU
    rt_set_runnable_on_cpuid(PLLRefGen_Task, 1);
    //Convert samp_time, which is in nanoseconds, to tick time
    //sampling_interval = nano2count(SAMP_TIME);  //Converts a value from
                                                //nanoseconds to internal count units.
    mlockall(MCL_CURRENT|MCL_FUTURE);
    rt_make_hard_real_time();
    PLLUpdateTime = nano2count(PLLGenerationLoopTime);
    rt_printk("PLL generation update time is %f12 \n",count2nano((float) PLLUpdateTime));
    // Let's make this task periodic..
    expected = rt_get_time() + 100*PLLUpdateTime;



    rt_task_make_periodic(PLLRefGen_Task, expected, PLLUpdateTime); //period in counts
    //rt_task_resume(Sinewaveloop_Task);
    PLLGenerationOn = TRUE;



    // Concurrent function Loop


     //rt_printk("SineWaveAmplitude is is %f \n",SineWaveAmplitude);
     //rt_printk("SineWaveFrequency is %f \n",SineWaveFrequency);
     //rt_printk("sine_loop_running is %d \n",sine_loop_running);
     //rt_printk("SAMP_TIME is %d \n",SAMP_TIME);
     start_time = (float)rt_get_time_ns()/1E9; //in seconds
     old_time = start_time;
     rt_printk("PLLReferenceGenerationChannel board_it is %p \n",PLLReferenceGenerationChannel.board_id);
     rt_printk("PLLReferenceGenerationChannel devicename is %p \n",*(PLLReferenceGenerationChannel.devicename));
     rt_printk("PLLReferenceGenerationChannel boardname is %p \n",*(PLLReferenceGenerationChannel.boardname));
     rt_printk("PLLReferenceGenerationChannel subdevice is %d \n",PLLReferenceGenerationChannel.subdevice);
     rt_printk("PLLReferenceGenerationChannel channel is %d \n",PLLReferenceGenerationChannel.channel);
     OutputValue = 1;
     PLLGenerationBufferSize = comedi_get_buffer_size(dev, PLLReferenceGenerationChannel.subdevice);
     //sine_loop_running = 0;  //set this to 0 for testing
     while(PLLGenerationOn)
     {
        i++; // Count Loops.
        current_time = (float)rt_get_time_ns()/1E9;
        //rt_printk("LOOP %d,-- Period time: %f12 %f12\n",i, current_time - old_time,count2nano((float)sampling_interval)/1E9);
        OutputValue = SineWaveAmplitude*sin(2*PI*SineWaveFrequency*(current_time-start_time));
        //OutputValue = -1*OutputValue;
        //rt_printk("OutputValue is %f12 \n",OutputValue);
        data_to_card = (lsampl_t) nearbyint(((OutputValue - MinOutputVoltage)/OutputRange)*MaxOutputBits);
        //m=rt_comedi_command_data_write(AnalogOutputChannel.board_id, AnalogOutputChannel.subdevice, NCHAN, data_to_card);
        comedi_lock(dev, AnalogOutputChannel.subdevice);
        m=comedi_data_write(dev, AnalogOutputChannel.subdevice, AnalogOutputChannel.channel, AO_RANGE, AREF_DIFF, data_to_card);
        comedi_unlock(dev, AnalogOutputChannel.subdevice);
//        m=comedi_data_write(AnalogOutputChannel.board_id, AnalogOutputChannel.subdevice,
//               AnalogOutputChannel.channel, AO_RANGE, AREF_GROUND, data_to_card);
        //rt_printk("Data_to_card is %d; result from rt_comedi_command_data_write is %d \n",data_to_card, m);
        //rt_printk("LOOP %d,-- AO Out time: %f12 \n",i, (float)rt_get_time_ns()/1E9 - current_time);
        //rt_printk("Data_to_card is %d \n",data_to_card);
        //old_time = current_time;
/*        if (i== 100000)
        {
            sine_loop_running = 0;
            //printf("LOOP -- run: %d %d\n ",keep_on_running,&keep_on_running);
            //printf("RTAI LOOP -- run: %d \n ",i);
            break;
        }
*/
        rt_task_wait_period(); // And waits until the end of the period.

    }
    rt_make_soft_real_time();
    comedi_close(dev);
    rt_task_delete(Sinewaveloop_Task); //Self termination at end.

    pthread_exit(NULL);
    return 0;
 }
int32 ATIDAQHardwareInterface::ConfigSingleSampleTask( float64 sampleRate,
                                                       int averaging,
                                                       const std::string & deviceName,
                                                       int firstChannel,
                                                       int numChannels,
                                                       int minVoltage,
                                                       int maxVoltage )
{
    int32 retVal = 0; /*the return value  <0 is err >0 is warning, 0 ok*/


    /*we have to use unmanaged c-style strings in here because that's what the NI-DAQmx
        C Library uses*/
    char channelString[WHOLE_LOTTA_CHARACTERS]; /*the channel string, of format "Dev1/ai0:5"*/
    /*set up member data*/
    m_f64SamplingFrequency = sampleRate;
    m_uiAveragingSize = ( averaging > 0 )? averaging : 1; /*averaging must be at least 1*/
    m_sDeviceName = deviceName;
    m_uiFirstChannel = firstChannel;
    m_uiNumChannels = numChannels;


    //for this we are using bipolar so do the reverse...
    //        if ( m_Calibration->BiPolar )
    //        {
    //             m_iMinVoltage += ( m_Calibration->VoltageRange / 2 );
    //            m_dLowerSaturationVoltage = m_iMinVoltage * GAUGE_SATURATION_LEVEL;
    //            m_iMaxVoltage += ( m_Calibration->VoltageRange / 2 );
    //            m_dUpperSaturationVoltage = m_iMaxVoltage * GAUGE_SATURATION_LEVEL;
    //        }
    //

    //make sure the out of range is returned as a number
    comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);

    m_iMinVoltage = minVoltage;
    m_iMaxVoltage = maxVoltage;

    range.max= m_iMaxVoltage;
    range.min= m_iMinVoltage;
    range.unit = UNIT_volt;
    //
    comediDev = comedi_open(m_sDeviceName.c_str());

    //error;
    if (comediDev == NULL) {
        comedi_perror(m_sDeviceName.c_str());
        return -1;
    }

    maxdata = comedi_get_maxdata(comediDev, 0,0);

    //create an instruction set to grab readings one by one.
    insn = new comedi_insn[m_uiNumChannels];
    dataArray = new lsampl_t[m_uiNumChannels];

    /* Set up a the "instruction list", which is just a pointer
           * to the array of instructions and the number of instructions.
           */
    il.n_insns = m_uiNumChannels;
    il.insns = insn;

    for (int chan = 0 ; chan < m_uiNumChannels ; chan ++){

        /* Instruction 1: do 10 analog input reads */
        insn[chan].insn = INSN_READ;
        insn[chan].n = 1;
        insn[chan].data = &(dataArray[chan]);
        insn[chan].subdev = 0;
        insn[chan].chanspec = CR_PACK(chan,0,AREF_DIFF);
    }

    // unsigned int numSamplesPerChannel = m_uiAveragingSize; /*the number of samples per channel that daqmx is configured with*/
    //        /*in a perfect world, NI-DAQmx would allow us to set up single scan acquisitions, but they don't.
    //        even if we were to make the single sample task a finite sample task, they still require you to use
    //        at least 2 samples per channel.  Therefore, we pass daqmx a number of samples per channel that it
    //        will accept, and then set up our task to only read the most recent samples*/
    //        if ( MIN_SAMPLES_PER_CHANNEL > numSamplesPerChannel ) numSamplesPerChannel = MIN_SAMPLES_PER_CHANNEL;
    //
    //        ati_Channel_Name_Format( channelString, m_sDeviceName );	/* Format the channel name for niDAQmx */
    //
    //        /*if the following confuses you, I suggest you read the NI-DAQmx C Reference Help, included
    //        with NI-DAQmx*/
    //        StopCollection(); /*stop currently running task*/
    //        /*if any function fails (returns non-zero), don't execute any more daqmx functions*/
    //        /*create the daqmx task*/
    //        if( !( retVal = DAQmxCreateTask( "", m_thDAQTask ) ) )
    //                /*add the analog input channels to the task - july.22.2005 - ss - now uses m_iConnectionMode*/
    //                if( !( retVal = DAQmxCreateAIVoltageChan( *m_thDAQTask, channelString, "", m_iConnectionMode,
    //                                        m_iMinVoltage, m_iMaxVoltage, DAQmx_Val_Volts, NULL ) ) )
    //                        /*set up timing for the task*/
    //                        if( !( retVal = DAQmxCfgSampClkTiming( *m_thDAQTask, NULL, m_f64SamplingFrequency,
    //                                                DAQmx_Val_Rising, DAQmx_Val_ContSamps, numSamplesPerChannel ) ) )
    //                                /*set read position relative to next sample to be read*/
    //                                if( !( retVal = DAQmxSetReadRelativeTo( *m_thDAQTask, DAQmx_Val_MostRecentSamp ) ) )
    //                                        /*offset of -1 from the next sample, meaning we read the most recent sample*/
    //                                        if( !( retVal = DAQmxSetReadOffset( *m_thDAQTask, 0 ) ) )
    //                                                /*start the task*/
    //                                                retVal = DAQmxStartTask( *m_thDAQTask );
    return retVal;
}