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; }
void writeCalibrationSet(const CalibrationSet &calibration, const std::string &driverName, const std::string &boardName, const std::string &filePath) { comedi_calibration_t *c_cal = static_cast<comedi_calibration_t *>(malloc(sizeof(comedi_calibration_t))); if(c_cal == 0) throw std::runtime_error("writeCalibrationSet: malloc failed\n"); memset(c_cal, 0, sizeof(comedi_calibration_t)); c_cal->driver_name = static_cast<char*>(malloc(driverName.size() + 1)); strcpy(c_cal->driver_name, driverName.c_str()); c_cal->board_name = static_cast<char*>(malloc(boardName.size() + 1)); strcpy(c_cal->board_name, boardName.c_str()); CalibrationSet::const_iterator it; for(it = calibration.begin(); it != calibration.end(); ++it) { const SubdeviceCalibration &subdeviceCalibration = it->second; std::map<std::pair<unsigned, unsigned>, Polynomial>::const_iterator jt; for(jt = it->second.polynomials().begin(); jt != it->second.polynomials().end(); ++jt) { comedi_calibration_setting_t *setting = sc_alloc_calibration_setting(c_cal); setting->subdevice = it->first; unsigned channel = jt->first.first; if(channel != SubdeviceCalibration::allChannels) { sc_push_channel(setting, channel); } unsigned range = jt->first.second; if(range != SubdeviceCalibration::allRanges) { sc_push_range(setting, range); } const Polynomial &polynomial = jt->second; comedi_polynomial_t *comediPolynomial = static_cast<comedi_polynomial_t*>(malloc(sizeof(comedi_polynomial_t))); assert(comediPolynomial); comediPolynomial->expansion_origin = polynomial.expansionOrigin; comediPolynomial->order = polynomial.order(); unsigned i; for(i = 0; i < polynomial.coefficients.size(); ++i) { assert(i < COMEDI_MAX_NUM_POLYNOMIAL_COEFFICIENTS); comediPolynomial->coefficients[i] = polynomial.coefficients.at(i); } if(subdeviceCalibration.toPhys()) { setting->soft_calibration.to_phys = comediPolynomial; }else { setting->soft_calibration.from_phys = comediPolynomial; } } } int retval = write_calibration_file(filePath.c_str(), c_cal); comedi_cleanup_calibration(c_cal); if(retval) { std::ostringstream message; message << __FUNCTION__ << ": write_calibration_file() failed."; throw std::runtime_error(message.str()); } }
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; }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Calibrator::calibrate // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void Calibrator::calibrate(void) { // Bring globals into scope extern GladeXML *gui; // Locals unsigned int seq_index, count; char label_text[50]; bool skip, started, paused; Sequence *seq; GtkWidget *label, *notify, *window, *progress_bar; vector< vector<float> > temp; Template sequence_template(NUMBER_OF_CHANNELS,sequences->length()); gdk_threads_enter(); // Get GDK lock progress_bar = glade_xml_get_widget(gui, "cal_progress_bar"); window = glade_xml_get_widget(gui, "cal_progress"); label = glade_xml_get_widget(gui, "cal_label"); notify = glade_xml_get_widget(gui, "cal_notify"); username = (const char*)gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(gui, "user_field"))); gdk_threads_leave(); // Release GDK lock for(seq_index = 0; seq_index < sequences->number(); ++seq_index) // calibrate for each sequence { // Reset calibration progress window sprintf(label_text, "Calibrate Sequence %d", seq_index+1); gdk_threads_enter(); // Get GDK lock gtk_widget_set_sensitive(glade_xml_get_widget(gui, "cal_skip"),TRUE); gtk_widget_set_sensitive(glade_xml_get_widget(gui, "cal_pause"),FALSE); gtk_label_set_text(GTK_LABEL(label),label_text); gdk_threads_leave(); // Release GDK lock update_cal_progress_window(-1); // wait for user to click start button do { gdk_threads_enter(); // Get GDK lock skip = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(gui, "cal_skip"))); gdk_threads_leave(); // Release GDK lock if(skip) { gdk_threads_enter(); // Get GDK lock gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(gui, "cal_skip")),FALSE); gdk_threads_leave(); ++seq_index; break; // return to beginning } gdk_threads_enter(); // Get GDK lock started = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(gui, "cal_start"))); gdk_threads_leave(); // Release GDK lock }while(!started); if (seq_index < sequences->number()) { gdk_threads_enter(); // Get GDK lock gtk_widget_set_sensitive(glade_xml_get_widget(gui, "cal_start"), FALSE); gtk_widget_set_sensitive(glade_xml_get_widget(gui, "cal_skip"),FALSE); gtk_widget_set_sensitive(glade_xml_get_widget(gui, "cal_pause"),TRUE); gdk_threads_leave(); // Release GDK lock // Reset the template sequence_template.reset(); // average PERIODS_TO_AVERAGE periods of EEG signal for(count = 0; count < PERIODS_TO_AVERAGE; ++count) { // Check pause button do { gdk_threads_enter(); paused = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(gui, "cal_pause"))); gdk_threads_leave(); for(unsigned i = 0; i < 10000; ++i); } while (paused); // Wait in loop temp = get_one_period(); if (!is_corrupt(temp) ) { sequence_template.add_data(temp); update_cal_progress_window(count); } else{ --count; } } sequence_template.generate_template(); seq = sequences->at(seq_index); seq->set_template(sequence_template); // Write cal file write_calibration_file(seq_index+1, sequence_template.get_template()); } // Reset toggle button gdk_threads_enter(); // Get GDK lock gtk_widget_set_sensitive(glade_xml_get_widget(gui, "cal_start"), TRUE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(gui, "cal_start")),FALSE); gdk_threads_leave(); // Release GDK lock } xval("xval.txt"); // Hide widget gdk_threads_enter(); // Get GDK lock gtk_widget_hide(window); gdk_threads_leave(); // Release GDK lock }