コード例 #1
0
ファイル: daq.c プロジェクト: nsaspook/cpanel
double get_adc_volts(int chan, int diff, int range)
{
	lsampl_t data[OVER_SAMPLE]; // adc burst data buffer
	int retval;
	comedi_range *ad_range;
	comedi_insn daq_insn;

	ADC_ERROR = FALSE; // global fault flag

	if (diff == TRUE) {
		aref_ai = AREF_DIFF;
	} else {
		aref_ai = AREF_GROUND;
	}

	// configure the AI channel for reads
	daq_insn.subdev = subdev_ai;
	daq_insn.chanspec = CR_PACK(chan, range, aref_ai);
	daq_insn.insn = INSN_READ;
	daq_insn.n = OVER_SAMPLE;
	daq_insn.data = data;

	retval = comedi_do_insn(it, &daq_insn); // send one instruction to the driver
	if (retval < 0) {
		comedi_perror("comedi_do_insn in get_adc_volts");
		ADC_ERROR = TRUE;
		bmc.raw[chan] = 0;
		return 0.0;
	}

	ad_range = comedi_get_range(it, subdev_ai, chan, range);
	bmc.raw[chan] = data[0];
	return comedi_to_phys(data[0], ad_range, maxdata_ai); // return the double result
}
コード例 #2
0
ファイル: acq_d.c プロジェクト: wibble/acq_d
/*
 * This prepares a command in a pretty generic way.  We ask the
 * library to create a stock command that supports periodic
 * sampling of data, then modify the parts we want. */
int prepare_cmd_lib(comedi_t *dev,struct parsed_options opt, comedi_cmd *cmd) {
	static unsigned int chanlist[256];
	int ranges[256];
	int ret;

	memset(cmd,0,sizeof(*cmd));

	/* This comedilib function will get us a generic timed
	 * command for a particular board.  If it returns -1,
	 * that's bad. */
	ret = comedi_get_cmd_generic_timed(dev,opt.subdevice, cmd,opt.n_chan,1e9/opt.freq);

	if(ret<0){
		printf("comedi_get_cmd_generic_timed failed\n");
		return ret;
	}

	/* Modify parts of the command */

	strtary(ranges,opt.ranges);
	if (opt.verbose) printf("Current range tokens: %i %i %i %i.\n",ranges[0],ranges[1],ranges[2],ranges[3]);

	for (unsigned short int i = 0; i < opt.n_chan; i++) {
		chanlist[i] = CR_PACK(i,ranges[i],AREF);
	}

	cmd->chanlist = chanlist;
	cmd->chanlist_len = opt.n_chan;
	cmd->stop_arg = opt.samples*DMA_OVERSCAN_MULT;

	return 0;
}
コード例 #3
0
ファイル: rmtest.c プロジェクト: ArcEye/RTAI
int test_cmd(void)
{
	int ret, i;
	comedi_cmd cmd;
	unsigned int chanlist[NCHAN];
	unsigned int buf_read[NCHAN] = { 2, 3, 4, 5, 6 };
  
	memset(&cmd, 0, sizeof(cmd));
	for (i = 0; i < NCHAN; i++) {
		chanlist[i] = CR_PACK(buf_read[i], AI_RANGE, AREF_GROUND);
	}

	cmd.subdev = subdevai;
	cmd.flags = TRIG_RT | TRIG_WAKE_EOS;

	cmd.start_src = TRIG_NOW;
	cmd.start_arg = 0;

	cmd.scan_begin_src = TRIG_TIMER;
	cmd.scan_begin_arg = SAMP_TIME; 

	cmd.convert_src = TRIG_TIMER;
	cmd.convert_arg = 2000;

	cmd.scan_end_src = TRIG_COUNT;
	cmd.scan_end_arg = NCHAN;

	cmd.stop_src = TRIG_NONE;
	cmd.stop_arg = 0;
	
	cmd.chanlist = chanlist;
	cmd.chanlist_len = NCHAN;

	PRINT("SENT COMMAND, subdev = %u, flags = %u, start_src = %u, start_arg = %u, scan_begin_src = %u, scan_begin_arg = %u, convert_src = %u, convert_arg = %u, scan_end_src = %u, scan_end_arg = %u, stop_src = %u, stop_arg = %u, chanlist_len = %u.\n", cmd.subdev, cmd.flags, cmd.start_src, cmd.start_arg, cmd.scan_begin_src, cmd.scan_begin_arg, cmd.convert_src, cmd.convert_arg, cmd.scan_end_src, cmd.scan_end_arg, cmd.stop_src, cmd.stop_arg, cmd.chanlist_len);
	for (i = 0; i < NCHAN; i++) {
		PRINT("CHALIST, # %d, val = %u.\n", i, chanlist[i]);
	}

	cmd.scan_begin_src = TRIG_TIMER;
	cmd.scan_begin_arg = SAMP_TIME; 

	cmd.convert_src = TRIG_TIMER;
	cmd.convert_arg = 2000;

	cmd.scan_end_src = TRIG_COUNT;
	cmd.scan_end_arg = NCHAN;

	cmd.stop_src = TRIG_NONE;
	cmd.stop_arg = 0;
	
	cmd.chanlist = chanlist;
	cmd.chanlist_len = NCHAN;

	ret = RT_comedi_command_test(daqnode, daqport, dev, &cmd);
	PRINT("Comedi_command_test returned: %d.\n", ret);
	ret = RT_comedi_command(daqnode, daqport, dev, &cmd);
	PRINT("Comedi_command returned: %d.\n", ret);

	return 0;
}
コード例 #4
0
ファイル: poll.c プロジェクト: olsonse/comedilib
int main(int argc, char *argv[])
{
	comedi_cmd cmd;
	int i;
	struct parsed_options options;

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

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

	fcntl(comedi_fileno(device), F_SETFL, O_NONBLOCK);

	for(i = 0; i < n_chans; i++){
		chanlist[i] = CR_PACK(options.channel + i, options.range, options.aref);
	}

	prepare_cmd(device, &cmd, options.subdevice);

	do_cmd(device, &cmd);

	return 0;
}
コード例 #5
0
ファイル: ledclock.c プロジェクト: jbetten/rtxi
/*
 * This part of the demo measures channels 1, 2, 3, 4 at a rate of
 * 10 khz, with the inter-sample time at 10 us (100 khz).  The number
 * of scans measured is 10.  This is analogous to the old mode2
 * acquisition.
 */
void prepare_cmd(comedi_t *dev, comedi_cmd *cmd, int subdevice)
{
	memset(cmd,0,sizeof(*cmd));

	/* the subdevice that the command is sent to */
	cmd->subdev = subdevice;

	/* flags */
	cmd->flags =		TRIG_WAKE_EOS;

	cmd->start_src =	TRIG_NOW;
	cmd->start_arg =	0;

	cmd->scan_begin_src =	TRIG_EXT;
	cmd->scan_begin_arg =	0;

#if 0
	cmd->convert_src =	TRIG_TIMER;
	cmd->convert_arg =	1;
#else
	cmd->convert_src =	TRIG_ANY;
	cmd->convert_arg =	0;
#endif

	cmd->scan_end_src =	TRIG_COUNT;
	cmd->scan_end_arg =	1;

	cmd->stop_src =		TRIG_NONE;
	cmd->stop_arg =		0;

	cmd->chanlist =		chanlist;
	cmd->chanlist_len =	1;

	chanlist[0]=CR_PACK(0,0,0);
}
コード例 #6
0
ファイル: comedi.c プロジェクト: braice/Laser-Lock
int prepare_comedi_command(comedi_t *card, comedi_cmd *cmd, int *channels, int n_channels, int range,int period, int n_samples)
{
  static unsigned int chanlist[16];
  memset(cmd,0,sizeof(comedi_cmd));
  /* fill in the command data structure: */
  cmd->subdev         = SUBDEV;
  cmd->flags          = 0;
  /*The start of an acquisition is controlled by the start_src events. The available options are:
      * TRIG_NOW: the start_src event occurs start_arg nanoseconds after the comedi_cmd is called. Currently, only start_arg=0 is supported.
      * TRIG_FOLLOW: (For an output device.) The start_src event occurs when data is written to the buffer.
      * TRIG_EXT: the start event occurs when an external trigger signal occurs; e.g., a rising edge of a digital line. start_arg chooses the particular digital line.
      * TRIG_INT: the start event occurs on a Comedi internal signal, which is typically caused by an INSN_INTTRIG instruction.
      */
  cmd->start_src      = TRIG_EXT;
  cmd->start_arg      = 0;
  /*The start of the beginning of each scan is controlled by the scan_begin events. The available options are:
      * TRIG_TIMER: scan_begin events occur periodically. The time between scan_begin events is convert_arg nanoseconds.
      * TRIG_FOLLOW: The scan_begin event occurs immediately after a scan_end event occurs.
      * TRIG_EXT: the scan_begin event occurs when an external trigger signal occurs; e.g., a rising edge of a digital line. scan_begin_arg chooses the particular digital line.
      */
  cmd->scan_begin_src = TRIG_FOLLOW;
  cmd->scan_begin_arg = 0;
  /* The timing between each sample in a scan is controlled by the convert_* fields:
       * TRIG_TIMER: the conversion events occur periodically. The time between convert events is convert_arg nanoseconds.
       * TRIG_EXT: the conversion events occur when an external trigger signal occurs, e.g., a rising edge of a digital line. convert_arg chooses the particular digital line.
       * TRIG_NOW: All conversion events in a scan occur simultaneously.
   */
  cmd->convert_src    = TRIG_TIMER;
  cmd->convert_arg    = period;
  /* The end of an acquisition is controlled by stop_src and stop_arg:
       * TRIG_COUNT: stop the acquisition after stop_arg scans.
       * TRIG_NONE: perform continuous acquisition, until stopped using comedi_cancel().
          Its argument is reserved and should be set to 0. ("Reserved" means that unspecified things could happen if it is set to something else but 0.)
  */
  cmd->scan_end_src   = TRIG_COUNT;
  cmd->scan_end_arg   = n_channels;

  cmd->stop_src       = TRIG_COUNT;
  cmd->stop_arg       = n_samples;

  cmd->chanlist       = chanlist; // pointer to list of channels to be sampled
  cmd->chanlist_len   = n_channels;        // number of channels to be sampled

  //We configure the channel
  int i;
  for(i=0;i<n_channels;i++)
    chanlist[i] = CR_PACK(channels[i],range,aref);

  
  //We test the command
  int ret;
  ret=comedi_command_test(card,cmd);
  if (ret)
    printf("result of command test : %d\n",ret);

  return ret;

}
コード例 #7
0
ファイル: data.c プロジェクト: AppEngine/linux-2.6
int comedi_data_write(void *dev, unsigned int subdev, unsigned int chan,
	unsigned int range, unsigned int aref, unsigned int data)
{
	struct comedi_insn insn;

	memset(&insn, 0, sizeof(insn));
	insn.insn = INSN_WRITE;
	insn.n = 1;
	insn.data = &data;
	insn.subdev = subdev;
	insn.chanspec = CR_PACK(chan, range, aref);

	return comedi_do_insn(dev, &insn);
}
コード例 #8
0
ファイル: data.c プロジェクト: johnny/CobraDroidBeta
int comedi_data_read(comedi_t * dev, unsigned int subdev, unsigned int chan,
	unsigned int range, unsigned int aref, lsampl_t * data)
{
	comedi_insn insn;

	memset(&insn, 0, sizeof(insn));
	insn.insn = INSN_READ;
	insn.n = 1;
	insn.data = data;
	insn.subdev = subdev;
	insn.chanspec = CR_PACK(chan, range, aref);

	return comedi_do_insn(dev, &insn);
}
コード例 #9
0
int comedi_dio_config(struct comedi_device *dev, unsigned int subdev,
		      unsigned int chan, unsigned int io)
{
	struct comedi_insn insn;

	memset(&insn, 0, sizeof(insn));
	insn.insn = INSN_CONFIG;
	insn.n = 1;
	insn.data = &io;
	insn.subdev = subdev;
	insn.chanspec = CR_PACK(chan, 0, 0);

	return comedi_do_insn(dev, &insn);
}
コード例 #10
0
ファイル: data.c プロジェクト: AppEngine/linux-2.6
int comedi_data_read_hint(void *dev, unsigned int subdev,
	unsigned int chan, unsigned int range, unsigned int aref)
{
	struct comedi_insn insn;
	unsigned int dummy_data;

	memset(&insn, 0, sizeof(insn));
	insn.insn = INSN_READ;
	insn.n = 0;
	insn.data = &dummy_data;
	insn.subdev = subdev;
	insn.chanspec = CR_PACK(chan, range, aref);

	return comedi_do_insn(dev, &insn);
}
コード例 #11
0
ファイル: cmd.c プロジェクト: ArcEye/RTAI
int do_cmd(void)
{
	int ret, i;
	comedi_cmd cmd;
	unsigned int chanlist[NCHAN];
	unsigned int buf_read[NCHAN] = { 2, 3, 4, 5, 6 };
  
	memset(&cmd, 0, sizeof(cmd));
	for (i = 0; i < NCHAN; i++) {
		chanlist[i] = CR_PACK(buf_read[i], AI_RANGE, AREF_GROUND);
	}

	cmd.subdev = subdev;
	cmd.flags = TRIG_RT | TRIG_WAKE_EOS;

	cmd.start_src = TRIG_NOW;
	cmd.start_arg = 0;

	cmd.scan_begin_src = TRIG_TIMER;
	cmd.scan_begin_arg = SAMP_TIME; 

	cmd.convert_src = TRIG_TIMER;
	cmd.convert_arg = 2000;

	cmd.scan_end_src = TRIG_COUNT;
	cmd.scan_end_arg = NCHAN;

	cmd.stop_src = TRIG_NONE;
	cmd.stop_arg = 0;
	
	cmd.chanlist = chanlist;
	cmd.chanlist_len = NCHAN;

	ret = comedi_command_test(dev, &cmd);
	printf("1st comedi_command_test returned: %d.\n", ret);
	ret = comedi_command_test(dev, &cmd);		
	printf("2nd comedi_command_test returned: %d.\n", ret);
	printf("CONVERT ARG: %d\n", cmd.convert_arg);

	if (ret) {
		return ret;
	}

	ret = comedi_command(dev, &cmd);
	printf("Comedi_command returned: %d.\n", ret);

	return ret;
}
コード例 #12
0
ファイル: aocmd.c プロジェクト: cjecho/RTAI
int do_cmd(void)
{
	int ret, i;
	unsigned int chanlist[NCHAN];
	unsigned int buf_write[NCHAN] = { 0, 1 };

	memset(&cmd, 0, sizeof(cmd));
	for (i = 0; i < NCHAN; i++) {
		chanlist[i] = CR_PACK(buf_write[i], AO_RANGE, AREF_GROUND);
	}

	cmd.subdev = subdev;
	cmd.flags = TRIG_RT | TRIG_WRITE;

	cmd.start_src = TRIG_INT;
	cmd.start_arg = 0;

	cmd.scan_begin_src = TRIG_TIMER;
	cmd.scan_begin_arg = SAMP_TIME;

	cmd.convert_src = TRIG_NOW;
	cmd.convert_arg = 0;

	cmd.scan_end_src = TRIG_COUNT;
	cmd.scan_end_arg = NCHAN;

	cmd.stop_src = TRIG_NONE;
	cmd.stop_arg = 0;

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

	ret = comedi_command_test(dev, &cmd);
	ret = comedi_command_test(dev, &cmd);

	if (ret) {
		return ret;
	}

	ret = comedi_command(dev, &cmd);

	return ret;
}
コード例 #13
0
ファイル: rttest.c プロジェクト: glutamate/bugpan
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;
}
コード例 #14
0
ファイル: daq.c プロジェクト: nsaspook/mbmc
double get_adc_volts(int chan, int diff, int range)
{
	lsampl_t data[OVER_SAMPLE];	// adc burst data buffer
	int retval, intg, i;
	comedi_range *ad_range;
	comedi_insn daq_insn;

	ADC_ERROR = FALSE;	// global fault flag

	if (diff == TRUE) {
		aref_ai = AREF_DIFF;
	} else {
		aref_ai = AREF_GROUND;
	}

	intg = 0;	// clear the integration counter
	// configure the AI channel for burst reads of OVER_SAMPLE times with the passed params
	daq_insn.subdev = subdev_ai;
	daq_insn.chanspec = CR_PACK(chan, range, aref_ai);
	daq_insn.insn = INSN_READ;
	daq_insn.n = OVER_SAMPLE;
	daq_insn.data = data;

	retval = comedi_do_insn(it, &daq_insn); // send one instruction to the driver
	if (retval < 0) {
		comedi_perror("comedi_do_insn in get_adc_volts");
		ADC_ERROR = TRUE;
		bmc.raw[chan] = 0;
		return 0.0;
	}
	for (i = 0; i < OVER_SAMPLE; i++) {
		intg += data[i];
	}
	data[0] = intg >> OVER_SAMPLE_SHIFTS;

	ad_range = comedi_get_range(it, subdev_ai, chan, range);
	bmc.raw[chan] = data[0];
	return comedi_to_phys(data[0], ad_range, ((1 << (OVER_SAMPLE_ADC + OVER_SAMPLE_BITS)) - 1)); // return the double result
}
コード例 #15
0
ファイル: sigio.c プロジェクト: jbetten/rtxi
/*
 * This part of the demo measures channels 1, 2, 3, 4 at a rate of
 * 10 khz, with the inter-sample time at 10 us (100 khz).  The number
 * of scans measured is 10.  This is analogous to the old mode2
 * acquisition.
 */
void do_cmd_1(comedi_t *dev, int subdevice)
{
	comedi_cmd cmd;

	memset(&cmd,0,sizeof(cmd));

	/* the subdevice that the command is sent to */
	cmd.subdev = subdevice;

	/* flags */
	cmd.flags =	TRIG_WAKE_EOS;

	cmd.start_src =		TRIG_NOW;
	cmd.start_arg =		0;

	cmd.scan_begin_src =	TRIG_TIMER;
	cmd.scan_begin_arg =	msec_to_nsec(100);

#if 1
	cmd.convert_src =	TRIG_TIMER;
	cmd.convert_arg =	1;
#else
	cmd.convert_src =	TRIG_ANY;
	cmd.convert_arg =	0;
#endif

	cmd.scan_end_src =	TRIG_COUNT;
	cmd.scan_end_arg =	1;

	cmd.stop_src =		TRIG_NONE;
	cmd.stop_arg =		0;

	cmd.chanlist =		chanlist;
	cmd.chanlist_len =	1;

	chanlist[0]=CR_PACK(0,0,0);

	do_cmd(dev,&cmd);
}
コード例 #16
0
ファイル: main.c プロジェクト: chandranorth/RTSPM
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;
 }
コード例 #17
0
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);

}
コード例 #18
0
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()) );
}
コード例 #19
0
ファイル: mmap.c プロジェクト: olsonse/comedilib
int test_mmap(void)
{
	comedi_cmd cmd;
	unsigned char *buf;
	unsigned int chanlist[1];
	int go;
	int fails;
	int total=0;
	int ret;
	void *b;
	unsigned char *adr;
	unsigned char *map;
	unsigned int flags;
	int i;
	unsigned sample_size;
	unsigned map_len;

	flags = comedi_get_subdevice_flags(device,subdevice);

	/* attempt to make subdevice the current 'read' subdevice */
	if(flags&SDF_CMD_READ) comedi_set_read_subdevice(device,subdevice);
	if(!(flags&SDF_CMD) || (comedi_get_read_subdevice(device)!=subdevice)){
		printf("not applicable\n");
		return 0;
	}
	if(flags & SDF_LSAMPL) sample_size = sizeof(lsampl_t);
	else sample_size = sizeof(sampl_t);
	map_len = sample_size * N_SAMPLES;

	if(comedi_get_cmd_generic_timed(device, subdevice, &cmd, 1, 1)<0){
		printf("E: comedi_get_cmd_generic_timed failed\n");
		return 0;
	}

	buf=malloc(sample_size * N_SAMPLES);

	map = mmap(NULL, map_len,PROT_READ, MAP_SHARED, comedi_fileno(device),0);
	if(!map){
		printf("E: mmap() failed\n");
		return 0;
	}

	/* test readability */
	for(adr = map; adr < map + map_len; adr += PAGE_SIZE){
		ret=test_segfault(adr);
		if(ret){
			printf("E: %p failed\n",adr);
		}else{
			printf("%p ok\n",adr);
		}
	}

	if(realtime)cmd.flags |= TRIG_RT;

	cmd.chanlist = chanlist;
	cmd.scan_end_arg = 1;
	cmd.stop_arg = N_SAMPLES;
	cmd.chanlist_len = 1;
	chanlist[0] = CR_PACK(0,0,0);

	comedi_command(device,&cmd);

	go=1;
	b=buf;
	while(go){
		ret = read(comedi_fileno(device), b,
				(N_SAMPLES * sample_size) - total);
		if(ret<0){
			if(errno==EAGAIN){
				usleep(10000);
			}else{
				go = 0;
				perror("read");
			}
		}else if(ret==0){
			go = 0;
		}else{
			total += ret;
			b += ret;
			if(verbose) printf("read %d %d\n",ret,total);
			if(total >= (N_SAMPLES * sample_size)){
				go = 0;
			}
		}
	}

	fails = 0;
	for(i=0;i<total;i++){
		if(buf[i]!=map[i]){
			if(fails==0)printf("E: mmap compare failed\n");
			printf("offset %d (read=%02x mmap=%02x)\n",i,
				buf[i], map[i]);
			fails++;
			if(fails>10)break;
		}
	}
	if(fails==0) printf("compare ok\n");

	munmap(map, map_len);

	/* test if area is really unmapped */
	for(adr = map; adr < map + map_len; adr += PAGE_SIZE){
		ret=test_segfault(adr);
		if(ret){
			printf("%p segfaulted (ok)\n",adr);
		}else{
			printf("E: %p still mapped\n",adr);
		}
	}

	free(buf);

	return 0;
}
コード例 #20
0
ファイル: bogio.c プロジェクト: nickbailey/bogiolib
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;
}
コード例 #21
0
ファイル: pwm.c プロジェクト: olsonse/comedilib
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;
}
コード例 #22
0
ファイル: comediModule.c プロジェクト: Ryuk4/crappy
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;
}
コード例 #23
0
ファイル: myBoard.c プロジェクト: emayssat/epics-iocs
static int prepareCommand( int board ) {
    MY_BOARD_HARDWARE *pBoardHard = myBoard_getHardwareBoard( board );
    MY_BOARD_SOFTWARE *pBoardSoft = myBoard_getSoftwareBoard( board );

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

    unsigned int pChannelList[MAX_CHANNEL_PER_BOARD];
    int i;

    comedi_cmd *pCmd = (comedi_cmd *)calloc( 1,sizeof(comedi_cmd) );
    memset( pCmd, 0, sizeof(comedi_cmd) );

    pCmd->subdev = pBoardHard->subDeviceNumber;
    pCmd->flags = 0;

    if (pBoardHard->internalClockFrequency > 0) {
        pCmd->start_src = TRIG_NOW;
        pCmd->start_arg = 0;

        pCmd->scan_begin_src = TRIG_TIMER;
        pCmd->scan_begin_arg = 1e9 / pBoardHard->internalClockFrequency;

        pCmd->convert_src = TRIG_TIMER;
        pCmd->convert_arg = 1;
    } else {
        pCmd->start_src = TRIG_EXT;
        pCmd->start_arg = 0;

        pCmd->scan_begin_src = TRIG_FOLLOW;
        pCmd->scan_begin_arg = 0;

        pCmd->convert_src = TRIG_EXT;
        pCmd->convert_arg = 0;
    }

    pCmd->scan_end_src = TRIG_COUNT;
    pCmd->scan_end_arg = pBoardSoft->numberOfActiveAnalogInputs;

    pCmd->stop_src = TRIG_NONE;
    pCmd->stop_arg = 0;

    for(i = 0;i < pBoardSoft->numberOfActiveAnalogInputs; i++){
        pChannelList[i] = CR_PACK(
            i,
            pBoardHard->channelIndexRange[i],
            pBoardHard->analogReference
        );
    }

    pCmd->chanlist = pChannelList;
    pCmd->chanlist_len = pBoardSoft->numberOfActiveAnalogInputs;
  
    int status; 
    status = comedi_command_test( pBoardHard->p_comediFileHandle, pCmd );
    status = comedi_command_test( pBoardHard->p_comediFileHandle, pCmd );
    if (status<0) {
        fprintf( stderr, "test command failed for board[%d]\n", board );
        return -1;
    }
    pBoardHard->p_comediCommand = pCmd;
    return 0;
}
コード例 #24
0
ファイル: myBoard.c プロジェクト: emayssat/epics-iocs
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;
}
コード例 #25
0
ファイル: ai_maxrate.c プロジェクト: gicmo/relacs
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;
}
コード例 #26
0
ファイル: cmd.c プロジェクト: grantad/Visualizing-Server-Data
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;
}
コード例 #27
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;
}