int init_daq(double min_range, double max_range, int range_update) { int i = 0; if (!DEV_OPEN) { it = comedi_open("/dev/comedi0"); if (it == NULL) { comedi_perror("comedi_open"); ADC_OPEN = FALSE; DEV_OPEN = FALSE; return -1; } DEV_OPEN = TRUE; } subdev_ai = comedi_find_subdevice_by_type(it, COMEDI_SUBD_AI, subdev_ai); if (subdev_ai < 0) { return -2; ADC_OPEN = FALSE; } subdev_ao = comedi_find_subdevice_by_type(it, COMEDI_SUBD_AO, subdev_ao); if (subdev_ao < 0) { HAS_AO = FALSE; } else { HAS_AO = TRUE; } printf("Subdev AI %i ", subdev_ai); channels_ai = comedi_get_n_channels(it, subdev_ai); printf("Analog Channels %i ", channels_ai); maxdata_ai = comedi_get_maxdata(it, subdev_ai, i); printf("Maxdata %i ", maxdata_ai); ranges_ai = comedi_get_n_ranges(it, subdev_ai, i); printf("Ranges %i ", ranges_ai); ad_range = comedi_get_range(it, subdev_ai, i, ranges_ai - 1); if (range_update) { ad_range->min = min_range; ad_range->max = max_range; } printf(": ad_range .min = %.3f, max = %.3f\n", ad_range->min, ad_range->max); if (HAS_AO) { printf("Subdev AO %i ", subdev_ao); channels_ao = comedi_get_n_channels(it, subdev_ao); printf("Analog Channels %i ", channels_ao); maxdata_ao = comedi_get_maxdata(it, subdev_ao, i); printf("Maxdata %i ", maxdata_ao); ranges_ao = comedi_get_n_ranges(it, subdev_ao, i); printf("Ranges %i ", ranges_ao); da_range = comedi_get_range(it, subdev_ao, i, ranges_ao - 1); printf(": da_range .min = %.3f, max = %.3f\n", da_range->min, da_range->max); } ADC_OPEN = TRUE; comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER); return 0; }
int init_dio(void) { int i = 0; if (!DEV_OPEN) { it = comedi_open(comedi_dev); if (it == NULL) { comedi_perror("comedi_open"); DIO_OPEN = FALSE; DEV_OPEN = FALSE; return -1; } DEV_OPEN = TRUE; } subdev_dio = comedi_find_subdevice_by_type(it, COMEDI_SUBD_DIO, subdev_dio); if (subdev_dio < 0) { return -1; DIO_OPEN = FALSE; } printf("Subdev %i ", subdev_dio); channels_dio = comedi_get_n_channels(it, subdev_dio); printf("Digital Channels %i ", channels_dio); maxdata_dio = comedi_get_maxdata(it, subdev_dio, i); printf("Maxdata %i ", maxdata_dio); ranges_dio = comedi_get_n_ranges(it, subdev_dio, i); printf("Ranges %i \n", ranges_dio); DIO_OPEN = TRUE; return 0; }
void ComediSubDeviceDOut::init(bool all_bits) { Logger::In in( nameserver.getName( this ).c_str() ); if (!myCard) { log(Error) << "Error creating ComediSubDeviceDOut: null ComediDevice given." <<endlog(); return; } if ( ( myCard->getSubDeviceType( subDevice ) != COMEDI_SUBD_DO ) && ( myCard->getSubDeviceType( subDevice ) != COMEDI_SUBD_DIO) ) { Logger::In in("ComediSubDeviceDOut"); log(Error) << "SubDevice "<< subDevice <<" is not a digital output:"; log() << "type = " << myCard->getSubDeviceType( subDevice ) << endlog(); // channels remains '0'. return; } channels = comedi_get_n_channels(myCard->getDevice()->it, subDevice); // Only for DIO if ( ( myCard->getSubDeviceType( subDevice ) == COMEDI_SUBD_DIO) && all_bits) { log(Info) << "Configuring first "<<channels<<" dio channels on subdevice "<<subDevice<<" as output type." << endlog(); for (unsigned int i=0; i<channels; ++i) comedi_dio_config(myCard->getDevice()->it, subDevice, i, COMEDI_OUTPUT); } else { log(Info) << "Subdevice "<<subDevice<<" is digital output with "<<channels << " channels." << endlog(); } }
int generic_cal_ao(calibration_setup_t *setup, const generic_layout_t *layout ) { int channel, range, num_ao_ranges, num_ao_channels, retval; comedi_calibration_setting_t *current_cal; if(setup->da_subdev >= 0 && setup->do_output) { assert( comedi_range_is_chan_specific( setup->dev, setup->da_subdev ) == 0 ); num_ao_ranges = comedi_get_n_ranges( setup->dev, setup->da_subdev, 0 ); if( num_ao_ranges < 0 ) return -1; num_ao_channels = comedi_get_n_channels( setup->dev, setup->da_subdev ); if( num_ao_channels < 0 ) return -1; }else num_ao_ranges = num_ao_channels = 0; for( channel = 0; channel < num_ao_channels; channel++ ) { for( range = 0; range < num_ao_ranges; range++ ) { current_cal = sc_alloc_calibration_setting(setup->new_calibration); generic_prep_dac_caldacs( setup, layout, channel, range ); generic_do_dac_channel( setup, layout, setup->new_calibration, current_cal, channel, range ); } } retval = write_calibration_file(setup->cal_save_file_path, setup->new_calibration); return retval; }
extern uchar init(char* dev) { uint i, nchan; ni = comedi_open(dev); if (ni == NULL) { printf("Error opening device\n"); return -1; } nchan = comedi_get_n_channels(ni, 0); printf("found comedi system with %d channels\n", nchan); for (i=0; i < nchan; i++) { if (comedi_dio_config(ni, 0, i, COMEDI_OUTPUT) < 0) return -1; } return 0; }
/*! \fn newViewDialog::slotPluginSelected() */ void newViewDialog::slotPluginSelected() { QString name = pluginsList->currentItem()->text(); okPushButton->setEnabled( TRUE ); QListIterator<pluginData> it(pl); while( it.hasNext() ){ pluginData data = it.next(); if ( data.name == name ){ maxSelect = data.numChannels; int comediSubdevice = comedi_find_subdevice_by_type(comediDevice,data.type_comedi,0); if( comediSubdevice >= 0){ maxChannels = comedi_get_n_channels(comediDevice, comediSubdevice); okPushButton->setEnabled(TRUE); status->setText(QString("comedi subdevice\ntype %1 found!").arg(data.type_comedi)); } else{ //comedi_perror( QString("error in %1 line %2").arg(__func__).arg(__LINE__).toStdString().c_str() ); okPushButton->setEnabled(FALSE); maxChannels = 0; status->setText(QString("comedi subdevice\ntype %1 not found!").arg(data.type_comedi)); } if( maxChannels < 0 ){ maxChannels = 0; comedi_perror( QString("error in %1 line %2").arg(__func__).arg(__LINE__).toStdString().c_str() ); } if(channelSelectors.count() < maxSelect) for( int i = channelSelectors.count(); i < maxSelect; i++ ) { QSpinBox *spinBox = new QSpinBox(); spinBox->setRange( 0, maxChannels-1 ); channelsListL->addWidget( spinBox ); channelSelectors << spinBox ; } else if(channelSelectors.count() > maxSelect) { channelSelectors.last(); for( int i = maxSelect; i< channelSelectors.count(); i++ ) delete channelSelectors.takeLast(); } } } }
int init_daq(void) { int i = 0, range_index = 0; comedi_range *ad_range; if (!DEV_OPEN) { it = comedi_open(comedi_dev); if (it == NULL) { comedi_perror("comedi_open"); ADC_OPEN = FALSE; DEV_OPEN = FALSE; HAVE_DIO = FALSE; HAVE_AI = FALSE; return -1; } DEV_OPEN = TRUE; } subdev_ai = comedi_find_subdevice_by_type(it, COMEDI_SUBD_AI, subdev_ai); if (subdev_ai < 0) { return -1; ADC_OPEN = FALSE; } printf("Subdev %i ", subdev_ai); channels_ai = comedi_get_n_channels(it, subdev_ai); printf("Analog Channels %i ", channels_ai); maxdata_ai = comedi_get_maxdata(it, subdev_ai, i); printf("Maxdata %i ", maxdata_ai); ranges_ai = comedi_get_n_ranges(it, subdev_ai, i); printf("Ranges %i ", ranges_ai); for (range_index = 0; range_index < ranges_ai; range_index++) { ad_range = comedi_get_range(it, subdev_ai, i, range_index); printf(": range %i, min = %.1f, max = %.1f ", range_index, ad_range->min, ad_range->max); } printf("\n"); ADC_OPEN = TRUE; comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER); return 0; }
int generic_cal_by_range( calibration_setup_t *setup, const generic_layout_t *layout ) { int channel, range, num_ai_ranges, num_ao_ranges, num_ao_channels, retval; comedi_calibration_setting_t *current_cal; int postgain_bip, postgain_unip; assert( comedi_range_is_chan_specific( setup->dev, setup->ad_subdev ) == 0 ); num_ai_ranges = comedi_get_n_ranges( setup->dev, setup->ad_subdev, 0 ); if( num_ai_ranges < 0 ) return -1; if(setup->da_subdev >= 0 && setup->do_output ) { assert( comedi_range_is_chan_specific( setup->dev, setup->da_subdev ) == 0 ); num_ao_ranges = comedi_get_n_ranges( setup->dev, setup->da_subdev, 0 ); if( num_ao_ranges < 0 ) return -1; num_ao_channels = comedi_get_n_channels( setup->dev, setup->da_subdev ); if( num_ao_channels < 0 ) return -1; }else num_ao_ranges = num_ao_channels = 0; if( layout->adc_postgain_offset( 0 ) >= 0 ) { /* bipolar postgain */ current_cal = sc_alloc_calibration_setting(setup->new_calibration); generic_do_adc_postgain_offset( setup, layout, current_cal, 0, 0 ); sc_push_channel( current_cal, SC_ALL_CHANNELS ); for( range = 0; range < num_ai_ranges; range++ ) if( is_bipolar( setup->dev, setup->ad_subdev, 0, range ) ) sc_push_range( current_cal, range ); postgain_bip = setup->caldacs[ layout->adc_postgain_offset( 0 ) ].value; /* unipolar postgain */ if( layout->do_adc_unipolar_postgain ) { current_cal = sc_alloc_calibration_setting(setup->new_calibration); generic_do_adc_postgain_offset( setup, layout, current_cal, 0, 1 ); sc_push_channel( current_cal, SC_ALL_CHANNELS ); } for( range = 0; range < num_ai_ranges; range++ ) if( is_unipolar( setup->dev, setup->ad_subdev, 0, range ) ) sc_push_range( current_cal, range ); postgain_unip = setup->caldacs[ layout->adc_postgain_offset( 0 ) ].value; }else postgain_bip = postgain_unip = -1; for( range = 0; range < num_ai_ranges; range++ ) { current_cal = sc_alloc_calibration_setting(setup->new_calibration); generic_prep_adc_caldacs( setup, layout, 0, range ); if( is_unipolar( setup->dev, setup->ad_subdev, 0, range ) ) update_caldac( setup, layout->adc_postgain_offset( 0 ), postgain_unip ); else update_caldac( setup, layout->adc_postgain_offset( 0 ), postgain_bip ); generic_do_adc_channel( setup, layout, current_cal, 0, range ); sc_push_channel( current_cal, SC_ALL_CHANNELS ); } for( channel = 0; channel < num_ao_channels; channel++ ) { for( range = 0; range < num_ao_ranges; range++ ) { current_cal = sc_alloc_calibration_setting(setup->new_calibration); generic_prep_dac_caldacs( setup, layout, channel, range ); generic_do_dac_channel( setup, layout, setup->new_calibration, current_cal, channel, range ); } } retval = write_calibration_file(setup->cal_save_file_path, setup->new_calibration); return retval; }
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()) ); }
/** * facq_comedi_misc_test_chanlist: * @dev: A comedi_t device. * @subindex: A subdevice index. * @chanlist: A #FacqChanlist object. * @err: A #GError. * * Checks if the provided #FacqChanlist, @chanlist, can be used with * the subdevice @subindex, in the device @dev. * * Returns: %TRUE if supported %FALSE in other case. */ gboolean facq_comedi_misc_test_chanlist(comedi_t *dev,guint subindex,const FacqChanlist *chanlist,GError **err) { GError *local_err = NULL; guint i = 0, len = 0, iochans_n = 0; guint n_channels = 0, n_ranges = 0, subd_flags = 0; guint chanspec = 0, chan = 0, range = 0, aref = 0, flags = 0; FacqChanDir dir = 0; gint subdevice_type = 0; g_return_val_if_fail(FACQ_IS_CHANLIST(chanlist),FALSE); len = facq_chanlist_get_length(chanlist); iochans_n = facq_chanlist_get_io_chans_n(chanlist); if(len < 1 || iochans_n == 0){ g_set_error(&local_err,FACQ_COMEDI_MISC_ERROR, FACQ_COMEDI_MISC_ERROR_FAILED, "Chanlist needs at least one I/O channel"); goto error; } subdevice_type = comedi_get_subdevice_type(dev,subindex); if(subdevice_type < 0){ g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR, FACQ_COMEDI_MISC_ERROR_FAILED, comedi_strerror(comedi_errno())); goto error; } subd_flags = comedi_get_subdevice_flags(dev,subindex); if(subd_flags < 0){ g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR, FACQ_COMEDI_MISC_ERROR_FAILED, comedi_strerror(comedi_errno())); goto error; } n_channels = comedi_get_n_channels(dev,subindex); if(n_channels < 0){ g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR, FACQ_COMEDI_MISC_ERROR_FAILED, comedi_strerror(comedi_errno())); goto error; } for(i = 0;i < len;i++){ chanspec = facq_chanlist_get_io_chanspec(chanlist,i); facq_chanlist_chanspec_to_src_values(chanspec, &chan,&range, &aref,&flags); dir = facq_chanlist_get_io_chan_direction(chanlist,i); n_ranges = comedi_get_n_ranges(dev,subindex,chan); if(n_ranges < 0){ g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR, FACQ_COMEDI_MISC_ERROR_FAILED, comedi_strerror(comedi_errno())); goto error; } if(!facq_comedi_misc_test_chanspec(n_channels,n_ranges, subd_flags,chan,range, aref,flags,dir, subdevice_type, &local_err)) goto error; } return TRUE; error: if(local_err) g_propagate_error(err,local_err); return FALSE; }
unsigned int ComediSubDeviceDIn::nbOfInputs() const { if (!myCard) return 0; return comedi_get_n_channels(myCard->getDevice()->it, _subDevice); }
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); }
/** * @brief Get the information from Comedi library * */ void MainWindow::GetComediInfo() { int i,j; int n_subdevices,type; int chan,n_chans; int n_ranges; int subdev_flags; comedi_range *rng; ChannelList.clear(); // at the moment we are using the default device const char optionsfilename[]="/dev/comedi0"; QString DeviceName=AppSettings.value(Key_Comedi_Device_Name).toString(); if (DeviceName.length()<=0) DeviceName=optionsfilename; it = comedi_open(optionsfilename); if(!it) { QMessageBox::warning(this, optionsfilename, tr("Can not open the device\n"), QMessageBox::Ok); }; cbComediDevice->addItem(optionsfilename,1); AppSettings.setValue(Key_Comedi_Device_Name,DeviceName); QString buffer="Overall info:\n"; //buffer+=QString printf(" Version code: 0x%06x\n", comedi_get_version_code(it)); buffer+=QString(" Comedi version code: 0x%06x\n").arg(comedi_get_version_code(it)); buffer+=QString(" Driver name: %1\n").arg(comedi_get_driver_name(it)); buffer+=QString(" Board name: %1\n").arg(comedi_get_board_name(it)); n_subdevices = comedi_get_n_subdevices(it); buffer+=QString(" Number of subdevices: %1\n").arg(n_subdevices); tlComediInfo->setText(buffer); int channel_unique_id=1; // Now scan subdevices for(i = 0; i < n_subdevices; i++) { buffer.clear(); type = comedi_get_subdevice_type(it, i); if(type==COMEDI_SUBD_UNUSED) continue; QTextEdit * tabText=new QTextEdit; buffer+=QString("Subdevice %1\n").arg(i); buffer+=QString("Type: %1 (%2)\n").arg(type).arg(subdevice_types[type]); subdev_flags = comedi_get_subdevice_flags(it, i); QString flagsstring; flagsstring.sprintf("flags: 0x%08x\n",subdev_flags); buffer+=flagsstring; n_chans=comedi_get_n_channels(it,i); buffer+=QString(" Number of channels: %1\n").arg(n_chans); if ((type==1)||(type==2)) // Analog input or output { for(chan=0;chan<n_chans;chan++) { // here! ChannelList.append(AIO_channel(QString(optionsfilename),i,chan,0,type==1,++channel_unique_id)); }; }; if(!comedi_maxdata_is_chan_specific(it,i)) { buffer+=QString(" Maximal data value: %1\n").arg((unsigned long)comedi_get_maxdata(it,i,0)); } else { buffer+=QString(" Maximal data value is channel specific:\n"); for(chan=0;chan<n_chans;chan++) { buffer+=QString(" Channel %1: %2\n").arg(chan).arg ((unsigned long)comedi_get_maxdata(it,i,chan)); } }; buffer+=QString(" ranges:\n"); if (!comedi_range_is_chan_specific(it,i)) { n_ranges=comedi_get_n_ranges(it,i,0); buffer+=QString(" All channels:"); for(j=0;j<n_ranges;j++) { rng=comedi_get_range(it,i,0,j); // buffer+=QString(" [%g,%g]",rng->min,rng->max); buffer+=QString(" [%1,%2]").arg(rng->min).arg(rng->max); } buffer+=QString("\n"); } else { for (chan=0;chan<n_chans;chan++) { n_ranges=comedi_get_n_ranges(it,i,chan); printf(" chan%d:",chan); for(j=0;j<n_ranges;j++) { rng=comedi_get_range(it,i,chan,j); printf(" [%g,%g]",rng->min,rng->max); } printf("\n"); } } tabText->setText(buffer); tabWidget->addTab(tabText,QString("subdevice %1").arg(i)); } //printf(" command:\n"); //get_command_stuff(it,i); tabWidget->setTabText(0,tr("Connections")); // Create channles we might need; all are input channels save one Ini_ImI= new AIO_channel(Key_Im_Input,1); Ini_CmdI= new AIO_channel(Key_Cmd_Input,1); Ini_CmI= new AIO_channel(Key_Cm_Tlgf_Input,1); Ini_GainT= new AIO_channel(Key_Gain_Tlgf_Input,1); Ini_FreqT= new AIO_channel(Key_Freq_Tlgf_Input,1); Ini_LswT= new AIO_channel(Key_Lsw_Tlgf_Input,1); Ini_CmdO= new AIO_channel(Key_Cmd_Output,0); for (int ch=0;ch<ChannelList.count();ch++) { if (ChannelList[ch].is_input) { cbxAI_Im->addItem(ChannelList[ch].Description(),ChannelList[ch].ID()); if (ChannelList[ch]==Ini_ImI) { int zzz=cbxAI_Im->count(); cbxAI_Im->setCurrentIndex(zzz-1); }; cbxAI_Cmd->addItem(ChannelList[ch].Description(),ChannelList[ch].ID()); if (ChannelList[ch]==Ini_CmdI) { cbxAI_Cmd->setCurrentIndex(cbxAI_Cmd->count()-1); }; cbxAI_Cm_tlg->addItem(ChannelList[ch].Description(),ChannelList[ch].ID()); if (ChannelList[ch]==Ini_CmI) { cbxAI_Cm_tlg->setCurrentIndex(cbxAI_Cm_tlg->count()-1); }; cbxAI_Gain_tlg->addItem(ChannelList[ch].Description(),ChannelList[ch].ID()); if (ChannelList[ch]==Ini_GainT){ cbxAI_Gain_tlg->setCurrentIndex(cbxAI_Gain_tlg->count()-1); }; cbxAI_Freq_tlg->addItem(ChannelList[ch].Description(),ChannelList[ch].ID()); if (ChannelList[ch]==Ini_FreqT) { cbxAI_Freq_tlg->setCurrentIndex(cbxAI_Freq_tlg->count()-1); }; cbxAI_Lsw_tlg->addItem(ChannelList[ch].Description(),ChannelList[ch].ID()); if (ChannelList[ch]==Ini_LswT) { cbxAI_Lsw_tlg->setCurrentIndex(cbxAI_Lsw_tlg->count()-1); }; } else { cbxAO_Cmd->addItem(ChannelList[ch].Description(),ChannelList[ch].ID()); if (ChannelList[ch]==Ini_CmdO) { cbxAO_Cmd->setCurrentIndex(cbxAO_Cmd->count()-1); }; }; }; return; }
static void mdlStart(SimStruct *S) { #ifndef MATLAB_MEX_FILE void *dev; int subdev; int index = (int)COMEDI_DEVICE - 1; unsigned int channel = (unsigned int)COMEDI_CHANNEL; unsigned int range = (unsigned int)COMEDI_RANGE; int n_channels; char *devname[4] = {"/dev/comedi0","/dev/comedi1","/dev/comedi2","/dev/comedi3"}; char board[50]; static char_T errMsg[256]; comedi_krange krange; double range_min, range_max; if (!ComediDev[index]) { dev = comedi_open(devname[index]); if (!dev) { sprintf(errMsg, "Comedi open failed\n"); ssSetErrorStatus(S, errMsg); printf("%s", errMsg); return; } rt_comedi_get_board_name(dev, board); printf("COMEDI %s (%s) opened.\n\n", devname[index], board); ComediDev[index] = dev; } else { dev = ComediDev[index]; } if ((subdev = comedi_find_subdevice_by_type(dev, COMEDI_SUBD_AI, 0)) < 0) { sprintf(errMsg, "Comedi find_subdevice failed (No analog input)\n"); ssSetErrorStatus(S, errMsg); printf("%s", errMsg); comedi_close(dev); return; } if (!ComediDev_AIInUse[index] && comedi_lock(dev, subdev) < 0) { sprintf(errMsg, "Comedi lock failed for subdevice %d\n", subdev); ssSetErrorStatus(S, errMsg); printf("%s", errMsg); comedi_close(dev); return; } if ((n_channels = comedi_get_n_channels(dev, subdev)) < 0) { sprintf(errMsg, "Comedi get_n_channels failed for subdevice %d\n", subdev); ssSetErrorStatus(S, errMsg); printf("%s", errMsg); comedi_unlock(dev, subdev); comedi_close(dev); return; } if ((comedi_get_krange(dev, subdev, channel, range, &krange)) < 0) { sprintf(errMsg, "Comedi get range failed for subdevice %d\n", subdev); ssSetErrorStatus(S, errMsg); printf("%s", errMsg); comedi_unlock(dev, subdev); comedi_close(dev); return; } ComediDev_InUse[index]++; ComediDev_AIInUse[index]++; range_min = (double)(krange.min)*1.e-6; range_max = (double)(krange.max)*1.e-6; printf("AI Channel %d - Range : %1.2f [V] - %1.2f [V]\n", channel, range_min, range_max); ssGetPWork(S)[0] = (void *)dev; ssGetIWork(S)[0] = subdev; ssGetRWork(S)[0] = range_min; ssGetRWork(S)[1] = range_max; #endif }
static void init(scicos_block *block) { struct ADCOMDev * comdev = (struct ADCOMDev *) malloc(sizeof(struct ADCOMDev)); *block->work = (void *)comdev; char devName[15]; char board[50]; comedi_krange krange; comdev->channel = block->ipar[0]; comdev->range = block->ipar[1]; comdev->aref = block->ipar[2]; comdev->index = block->ipar[3]; sprintf(devName,"/dev/comedi%d", comdev->index); if (!ComediDev[comdev->index]) { comdev->dev = comedi_open(devName); if (!(comdev->dev)) { fprintf(stderr, "COMEDI %s open failed\n", devName); exit_on_error(); return; } rt_comedi_get_board_name(comdev->dev, board); printf("COMEDI %s (%s) opened.\n\n", devName, board); ComediDev[comdev->index] = comdev->dev; } else comdev->dev = ComediDev[comdev->index]; if ((comdev->subdev = comedi_find_subdevice_by_type(comdev->dev, COMEDI_SUBD_AI, 0)) < 0) { fprintf(stderr, "Comedi find_subdevice failed (No analog input)\n"); comedi_close(comdev->dev); exit_on_error(); return; } if (!ComediDev_AIInUse[comdev->index] && comedi_lock(comdev->dev, comdev->subdev) < 0) { fprintf(stderr, "Comedi lock failed for subdevice %d\n", comdev->subdev); comedi_close(comdev->dev); exit_on_error(); return; } if (comdev->channel >= comedi_get_n_channels(comdev->dev, comdev->subdev)) { fprintf(stderr, "Comedi channel not available for subdevice %d\n", comdev->subdev); comedi_unlock(comdev->dev, comdev->subdev); comedi_close(comdev->dev); exit_on_error(); return; } if ((comedi_get_krange(comdev->dev, comdev->subdev, comdev->channel, comdev->range, &krange)) < 0) { fprintf(stderr, "Comedi get_range failed for subdevice %d\n", comdev->subdev); comedi_unlock(comdev->dev, comdev->subdev); comedi_close(comdev->dev); exit_on_error(); return; } #ifdef SOFTCALIB int flags; if ((flags = comedi_get_subdevice_flags(comdev->dev, comdev->subdev)) < 0) { fprintf(stderr, "Comedi get_subdevice_flags failed for subdevice %d\n", comdev->subdev); } else { if (flags & SDF_SOFT_CALIBRATED) {/* board uses software calibration */ if ((comdev->use_softcal = get_softcal_coef(devName, comdev->subdev, comdev->channel, comdev->range, 0, comdev->coefficients)) == 0) fprintf(stderr, "No software calibration found for AI Channel %d\n",comdev->channel); } } #endif ComediDev_InUse[comdev->index]++; ComediDev_AIInUse[comdev->index]++; comdev->maxdata = comedi_get_maxdata(comdev->dev, comdev->subdev, comdev->channel); comdev->range_min = (double)(krange.min)*1.e-6; comdev->range_max = (double)(krange.max)*1.e-6; printf("AI Channel %d - Range : %1.2f [V] - %1.2f [V]%s\n\n", comdev->channel, comdev->range_min, comdev->range_max, (comdev->use_softcal)?" Software calibration used":""); }
static int openBoard( int board ) { MY_BOARD_HARDWARE *pBoardHard = myHardwareBoardList + board; MY_BOARD_SOFTWARE *pBoardSoft = mySoftwareBoardList + board; fprintf( stderr, "openBoard[%d]\n", board ); fprintf( stderr, "sizeof(lsampl_t)=%d\n", sizeof(lsampl_t) ); fprintf( stderr, "sizeof(sampl_t)=%d\n", sizeof(sampl_t) ); if (pBoardHard == NULL || pBoardSoft == NULL) return 1; pBoardHard->p_comediFileHandle = comedi_open( pBoardHard->devicePath ); if (pBoardHard->p_comediFileHandle == NULL) { fprintf( stderr, "comedi_open failed for board[%d] %s\n", board, pBoardHard->devicePath ); return 1; } fprintf( stderr, "opened file\n" ); pBoardHard->subDeviceNumber = comedi_find_subdevice_by_type( pBoardHard->p_comediFileHandle, COMEDI_SUBD_AI, 0 ); if (pBoardHard->subDeviceNumber < 0) { fprintf( stderr, "subDeviceNum < 0 failed for board[%d]\n", board ); return 1; } fprintf( stderr, "get subDevice=%d\n", pBoardHard->subDeviceNumber ); int subDevFlags = comedi_get_subdevice_flags( pBoardHard->p_comediFileHandle, pBoardHard->subDeviceNumber ); if (subDevFlags & SDF_PACKED) { fprintf( stderr, "subDevice using bit per channel\n" ); } else { if (subDevFlags & SDF_LSAMPL) { pBoardHard->valueIsLsampl_t = 1; fprintf( stderr, "subDevice using long word lsampl_t per channel\n" ); } else { fprintf( stderr, "subDevice using word sampl_t per channel\n" ); } } pBoardHard->buffer_size_in_byte = comedi_get_buffer_size( pBoardHard->p_comediFileHandle, pBoardHard->subDeviceNumber ); fprintf( stderr, "board[%d] hardware buffer size in BYTES=%d\n", board, pBoardHard->buffer_size_in_byte ); if (pBoardHard->buffer_size_in_byte <= 0) { fprintf( stderr, "board buffer size faile\n" ); return 1; } if (pBoardHard->valueIsLsampl_t) { pBoardHard->buffer_size_in_sample = pBoardHard->buffer_size_in_byte / sizeof(lsampl_t); } else { pBoardHard->buffer_size_in_sample = pBoardHard->buffer_size_in_byte / sizeof(sampl_t); } pBoardHard->buffer = mmap( NULL, pBoardHard->buffer_size_in_byte, PROT_READ, MAP_SHARED, comedi_fileno(pBoardHard->p_comediFileHandle), 0 ); if (pBoardHard->buffer == MAP_FAILED) { fprintf( stderr, "mmap failed for board[%d]\n", board ); return 1; } int numChannel = comedi_get_n_channels( pBoardHard->p_comediFileHandle, pBoardHard->subDeviceNumber ); if (numChannel != pBoardSoft->numberOfActiveAnalogInputs) { fprintf( stderr, "number of channel for board[%d] from comedi=%d harccode=%d\n", board, numChannel, pBoardSoft->numberOfActiveAnalogInputs ); } #ifdef SUPPORT_CHANNEL_SPECIFIC_RANGE pBoardHard->maxDataIsChannelSpecific = comedi_maxdata_is_chan_specific( pBoardHard->p_comediFileHandle, pBoardHard->subDeviceNumber ); pBoardHard->rangeIsChannelSpecific = comedi_maxdata_is_chan_specific( pBoardHard->p_comediFileHandle, pBoardHard->subDeviceNumber ); if (pBoardHard->maxDataIsChannelSpecific) { fprintf( stderr, "board[%d] supports different max data per channel\n", board ); } if (pBoardHard->rangeIsChannelSpecific) { fprintf( stderr, "board[%d] supports different range per channel\n", board ); } #endif return 0; }