void do_cmd(comedi_t *dev,comedi_cmd *cmd) { int total=0; int ret; int go; ret=comedi_command_test(dev,cmd); printf("test ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); comedi_perror("comedi_command_test"); return; } dump_cmd(stdout,cmd); ret=comedi_command_test(dev,cmd); printf("test ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); comedi_perror("comedi_command_test"); return; } dump_cmd(stdout,cmd); ret=comedi_command(dev,cmd); printf("ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); comedi_perror("comedi_command"); return; } go=1; while(go){ ret=read(comedi_fileno(dev),buf,BUFSZ); if(ret<0){ if(errno==EAGAIN){ printf("EAGAIN\n"); usleep(10000); }else{ go = 0; perror("read"); } }else if(ret==0){ go = 0; }else{ //int i; total+=ret; //printf("read %d %d\n",ret,total); //printf("count = %d\n",count); //print_time(); } } }
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; }
TEST(ComediTest,AnalogReadings ) { lsampl_t data; int ret; int subdev = 0; int chan = 0; int range = 0; int aref = AREF_GROUND; int num_scans = options.n_scan; int num_channels = options.n_chan; int readscans; std::string prop("/sys/class/comedi/comedi0/read_buffer_pos"); dev = comedi_open(options.filename); ASSERT_TRUE( dev ); subdev_flags = comedi_get_subdevice_flags(dev, options.subdevice); RecordProperty("NumScans", num_scans); #if 0 fprintf(stderr, "command before testing:\n"); dump_cmd(stderr, cmd); #endif prepare_cmd_lib(dev, options.subdevice, num_scans, num_channels, 1e9 / options.freq, cmd); #if 0 fprintf(stderr, "command before testing:\n"); dump_cmd(stderr, cmd); #endif /** * Setup the Command structure */ cmd->chanlist_len = 2; cmd->stop_arg = num_scans; /* verify no problems */ ret = comedi_command_test(dev, cmd); ASSERT_GE( ret, 0 ) << "Comedi Testing of command for device was ok"; /* make sure our scan number hasn't changed */ ASSERT_EQ( cmd->stop_arg , num_scans ); ASSERT_EQ( cmd->chanlist_len , 2 ); ret = comedi_command(dev, cmd); sleep(1); ASSERT_GE( ret, 0 ) << "Able to Submit comedi command\n"; /* Verify that the buffer position has in fact moved to say num_scans scans remain in it */ FILE *fp = fopen(prop.c_str(),"r"); ASSERT_TRUE( fp ) << "Able to open sysfs property file"; fscanf(fp,"%d",&readscans ); ASSERT_EQ( readscans, 4*num_scans ) << "Able to read the fifo position 4*" << num_scans << "\n"; fclose(fp); comedi_close( dev ); }
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; }
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; }
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; }
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()) ); }
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; }
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; }
void do_cmd(comedi_t *dev,comedi_cmd *cmd) { int total=0; int ret; int go; fd_set rdset; struct timeval timeout; ret=comedi_command_test(dev,cmd); printf("test ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); comedi_perror("comedi_command_test"); return; } dump_cmd(stdout,cmd); ret=comedi_command_test(dev,cmd); printf("test ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); comedi_perror("comedi_command_test"); return; } dump_cmd(stdout,cmd); ret=comedi_command(dev,cmd); printf("ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); comedi_perror("comedi_command"); return; } go=1; while(go){ FD_ZERO(&rdset); FD_SET(comedi_fileno(dev),&rdset); timeout.tv_sec = 0; timeout.tv_usec = 50000; ret = select(comedi_fileno(dev)+1,&rdset,NULL,NULL,&timeout); if(ret<0){ perror("select"); }else if(ret==0){ /* timeout */ }else if(FD_ISSET(comedi_fileno(dev),&rdset)){ ret=read(comedi_fileno(dev),buf,BUFSZ); if(ret<0){ if(errno==EAGAIN){ go = 0; perror("read"); } }else if(ret==0){ go = 0; }else{ //int i; total+=ret; //printf("read %d %d\n",ret,total); //printf("count = %d\n",count); do_toggle(); #if 0 for(i=0;i<ret;i+=sizeof(sampl_t)){ do_toggle(); } #endif } } } }
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; }
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); }
int main(int argc, char *argv[]) { comedi_cmd c,*cmd=&c; struct header_info header; long int t_samples, t_bytes, t_sleep; long int ret; int dt_usec, usec_elapsed; // struct timeval start,end; struct parsed_options options; unsigned short *samples; //, *junk; struct timeval now,then; long long unsigned int exec = 0; time_t t; umask(000); signal(SIGINT,do_depart); if (geteuid() != 0) { fprintf(stderr,"Must be setuid root to renice self.\n"); exit(0); } cmd_init_parsed_options(&options); cmd_parse_options(&options, argc, argv); t_samples = options.n_chan * options.samples; t_bytes = t_samples * 2; t_sleep = (long int) DMA_OVERSCAN_MULT*(1e6/options.freq)*options.samples; printf("freq = %f, tsamp = %li, tby = %li, tsleep = %li.\n",options.freq,t_samples,t_bytes,t_sleep); /* Test for failful options */ if (options.freq <= 1/(options.cadence + 0.00005)) { fprintf(stderr,"Acquisition frequency is faster than sampling frequency! FAIL!\n"); exit(ACQERR_BADINPUT); } if (options.samples > 16777216) { fprintf(stderr,"acq_d can't take more than 2^24 samples per set! Try acq_c.\n"); exit(ACQERR_BADINPUT); } ret = nice(-20); fprintf(stderr,"I've been niced to %li.\n",ret); if (ret != -20) printf(" WARNING!! Data collection could not set nice=-20. Data loss is probable at high speed."); dt_usec = options.cadence * 1e6; gettimeofday(&then, NULL); /* open the device */ dev = comedi_open(options.devfile); if (!dev) { comedi_perror(options.devfile); exit(ACQERR_BADDEV); } // printf("%li samples in %i-byte buffer.\n\n",t_samples,comedi_get_buffer_size(dev,options.subdevice)); prepare_cmd_lib(dev,options,cmd); printf("Testing command..."); 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(ACQERR_BADCMD); } printf("%s...",cmdtest_messages[ret]); ret = comedi_command_test(dev, cmd); printf("%s...",cmdtest_messages[ret]); ret = comedi_command_test(dev, cmd); printf("%s...\n",cmdtest_messages[ret]); if (ret < 0) { fprintf(stderr,"Bad command, and unable to fix.\n"); dump_cmd(stderr, cmd); exit(ACQERR_BADCMD); } dump_cmd(stdout,cmd); comedi_close(dev); //fprintf(stderr,"%i scan -- %i chan -- %li samples -- %li bytes\n",options.samples,options.n_chan,t_samples,t_bytes); /* Print data file header */ // sprintf(dataheader, "[system]\n" // "whoami = \"%s\"") samples = (unsigned short*) malloc(t_bytes); // junk = (unsigned short*) malloc(t_bytes); if ((samples == NULL)) { // | (junk == NULL)) { fprintf(stderr,"Error allocating sample memory!\n"); exit(ACQERR_BADMEM); } printf("Starting acquisition...\n"); /*Open the serial port*/ /*serial = (FILE*)fopen("/dev/ttyS0","w");*/ /* Do what we're here to do */ while (running) { if (exec == options.sets) { break; } exec++; serial_toggle(); /* open the device */ dev = comedi_open(options.devfile); if (!dev) { comedi_perror(options.devfile); exit(ACQERR_BADDEV); } gettimeofday(&now, NULL); usec_elapsed = (now.tv_sec - then.tv_sec) * 1e6 + (now.tv_usec - then.tv_usec); while (usec_elapsed < dt_usec) { usleep(USLEEP_GRAN); gettimeofday(&now, NULL); usec_elapsed = (now.tv_sec - then.tv_sec) * 1e6 + (now.tv_usec - then.tv_usec); } /* start the command */ ret = comedi_command(dev, cmd); if (ret < 0) { comedi_perror("comedi_command"); exit(ACQERR_BADCMD); } then = now; /* * Insert enough waiting to get through most of the sampling */ /*serial_toggle();*/ usleep(t_sleep); /* * Wait until the buffer has our data. */ int exsleeps = 0; do { usleep(USLEEP_GRAN); comedi_poll(dev,options.subdevice); ret = comedi_get_buffer_contents(dev,options.subdevice); exsleeps++; } while(ret < t_bytes); // printf("Waited %ius for additional data.\n",exsleeps); /* * Get teh dataz. */ ret = read(comedi_fileno(dev), samples, t_bytes); if (ret < t_bytes) { fprintf(stderr,"Read mismatch! Got %li of %li bytes (%li/%li samples).\n",ret,t_bytes,ret/2,t_samples); } header.num_read = ret/2; // collect & discard overscan /* ret = comedi_get_buffer_contents(dev,options.subdevice); if (realloc(junk,ret) == NULL) { fprintf(stderr,"Error in oversample realloc?\n"); exit(ACQERR_BADMEM); } if (ret > 0) { ret = read(comedi_fileno(dev),junk,ret); }*/ comedi_close(dev); // Prepare header t = time(NULL); sprintf(header.site_id,"%s",site_str); header.start_time = t; header.start_timeval = now; header.num_channels=options.n_chan; header.channel_flags=0x0F; header.num_samples=options.samples; header.sample_frequency=options.freq; header.time_between_acquisitions=options.cadence; header.byte_packing=0; header.code_version=current_code_version; // Save latest to monitor file if (strcmp(options.monfile,"") != 0) { out = open(options.monfile,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); ret = errno; if (out > 0) { ret = write(out,&header,sizeof(header)); ret = write(out,samples,2*header.num_read); close(out); } else { fprintf(stderr,"Unable to open monitor file %s: %s.\n",options.monfile,strerror(ret)); exit(ACQERR_BADOUT); } } if (options.cadence >= 1.0 && options.verbose) printf("\tSaved latest to: %s\n",options.monfile); // Append to output file if (strcmp(options.outfile,"") != 0) { out = open(options.outfile,O_WRONLY|O_APPEND|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); ret = errno; if (out > 0) { ret = write(out,samples,2*header.num_read); close(out); if (options.cadence >= 1.0 && options.verbose) printf("\tAppended to: %s\n",options.outfile); } else { fprintf(stderr,"Unable to open output file %s: %s.\n",options.outfile,strerror(ret)); exit(ACQERR_BADOUT); } } } if (dev != NULL) comedi_close(dev); if (out != 0) close(out); printf("\nEnd.\n"); exit(0); }
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; }
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; }
/** * Start the the ADC sampling, unless the external trigger command * is set it will begin sampling as soon as the usbdux device has been * initialized. * The final three arguments are very important to get right * as the recorder thread will use them to determine where to write it's samples and * when it's reached end of the buffer. It doesn't care about the c_buffer class * at all. * @param arg_device name of the comedi device e.g., 'comedi0' * @param arg_sample_rate the rate the usb_dux should sample with in hertz (max=3[Mhz]}) * @param arg_start_address the start address of the circle buffer sample should be loading into * @param arg_end_address the end address of the cicle buffer. * @param arg_buffer_size byte size of the buffer. */ int start_Sampling(char* arg_device, uint32_t arg_sample_rate, char* arg_start_address, char* arg_end_address, int arg_buffer_size){ _channel_amount = 16; _sample_rate = arg_sample_rate; unsigned int chanlist[_channel_amount]; unsigned int convert_arg = 1e9 / _sample_rate; int ret; comedi_cmd *cmd = (comedi_cmd *) calloc(1, sizeof(comedi_cmd)); _device = comedi_open(arg_device); int buffer = 1048576*40; buffer = (buffer * 4096)/4096; if(comedi_set_max_buffer_size(_device, 0, buffer) < 0 ){ printf("Failed to set max buffer size to %i bytes\n", buffer); return -1; } else printf("Maximum buffer size set to %i bytes\n", comedi_get_max_buffer_size(_device,0)); if(comedi_set_buffer_size(_device, 0, buffer) < 0){ printf("Failed to set buffer size to %iBytes\n", buffer); return -1; } else printf("Buffer size set to %iBytes\n", comedi_get_buffer_size(_device,0)); if(!_device){ errx(1, "unable to open device"); comedi_perror("/dev/comedi0"); return -1; } for(int i = 0; i < _channel_amount; i++) chanlist[i] = i; comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER); if((ret = comedi_get_cmd_generic_timed(_device, 0, cmd, _channel_amount,0)) < 0){ printf("comedi_get_cmd_generic_timed failed\n"); return ret; } cmd->chanlist = chanlist; cmd->stop_src = TRIG_NONE; cmd->stop_arg = 0; cmd->convert_arg = convert_arg; //setup the sampling to start from the trigger. //cmd->start_src = TRIG_EXT //cmd->start_arg = 1; /* call test twice because different things are tested? * if tests are successful run sampling command */ if((ret = comedi_command_test(_device, cmd)) != 0 || (ret = comedi_command_test(_device, cmd)) != 0 || (ret = comedi_command(_device, cmd)) < 0){ fprintf(stderr, "err: %d\n", ret); return -1; } FILE* dux_fp; if((dux_fp = fdopen(comedi_fileno(_device), "r")) <= 0) comedi_perror("fdopen"); char* write_address = arg_start_address; Utility::SNAP_SAMPLE = 0; Utility::LAST_SAMPLE = 0; uint64_t active_sample = 0; uint32_t tmp_block = 0; int samples_pr_block = 4096/sizeof(Type); while((ret = fread(write_address, 1, 4096,dux_fp)) >= 0){ write_address += 4096; tmp_block += 1; active_sample += samples_pr_block; Utility::LAST_SAMPLE += samples_pr_block; if(tmp_block >= Utility::SNAPSHOT_BLOCK_SIZE){ //printf("signalling serial snapshotter\n"); tmp_block = 0; Utility::SNAP_SAMPLE = active_sample; Utility::SNAP_READY = true; Utility::CV.notify_one(); } if(write_address == arg_end_address){ write_address -= arg_buffer_size; //printf("resetting to beginning of buffer\n"); } if(_stop == true) break; } if(ret < 0) perror("read"); comedi_cancel(_device, 0); return 0; }
void do_cmd(comedi_t *dev,comedi_cmd *cmd) { int total=0; int ret; int go; fd_set rdset; struct timeval timeout; ret=comedi_command_test(dev,cmd); printf("test ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); comedi_perror("comedi_command_test"); return; } dump_cmd(stdout,cmd); ret=comedi_command_test(dev,cmd); printf("test ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); comedi_perror("comedi_command_test"); return; } dump_cmd(stdout,cmd); comedi_set_read_subdevice(dev, cmd->subdev); ret = comedi_get_read_subdevice(dev); if (ret < 0 || ret != cmd->subdev) { fprintf(stderr, "failed to change 'read' subdevice from %d to %d\n", ret, cmd->subdev); return; } ret=comedi_command(dev,cmd); printf("ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); comedi_perror("comedi_command"); return; } go=1; while(go){ FD_ZERO(&rdset); FD_SET(comedi_fileno(device),&rdset); timeout.tv_sec = 0; timeout.tv_usec = 50000; ret = select(comedi_fileno(dev)+1,&rdset,NULL,NULL,&timeout); //printf("select returned %d\n",ret); if(ret<0){ perror("select"); }else if(ret==0){ /* hit timeout */ printf("timeout, polling...\n"); ret = comedi_poll(device,cmd->subdev); printf("poll returned %d\n",ret); }else if(FD_ISSET(comedi_fileno(device),&rdset)){ /* comedi file descriptor became ready */ //printf("comedi file descriptor ready\n"); ret=read(comedi_fileno(dev),buf,sizeof(buf)); printf("read returned %d\n",ret); if(ret<0){ if(errno==EAGAIN){ go = 0; perror("read"); } }else if(ret==0){ go = 0; }else{ int i; total+=ret; //printf("read %d %d\n",ret,total); for(i=0;i<ret/sizeof(sampl_t);i++){ printf("%d\n",buf[i]); } } }else{ /* unknown file descriptor became ready */ printf("unknown file descriptor ready\n"); } } }