static void alt_queue(FIBER_ALT *a) { FIBER_ALT_ARRAY *ar; ar = channel_array(a->c, a->op); array_add(ar, a); }
int main() { int i = 3; fprintf(stderr, "a"+i); try { SpectrumM2i40xxSeries* my_adc; ttlout trigger; trigger.id=0; trigger.ttls=0x400000; /* line 22 */// my_adc=new SpectrumM2i40xxSeries(trigger, 50.0, 1e7); state_sequent* test_sequence = new state_sequent(); state* test_state = new state(1); analogin* test_in = new analogin(); test_in->id = 0; //test_in->sensitivity = 5; test_in->sample_frequency = 2e7; test_in->resolution = 14; test_in->samples = 4096; test_in->channels = channel_array(15); test_in->nchannels = test_in->channels.count(); test_in->sensitivity = new double[4]; test_in->sensitivity[0] = 10.0; test_in->sensitivity[1] = 10.0; test_in->sensitivity[2] = 10.0; test_in->sensitivity[3] = 10.0; test_in->impedance = new double[4]; test_in->impedance[0] = 50.0; test_in->impedance[1] = 50.0; test_in->impedance[2] = 50.0; test_in->impedance[3] = 50.0; test_in->offset = new int[4]; test_in->offset[0] = -50; test_in->offset[1] = 0; test_in->offset[2] = 0; test_in->offset[3] = 0; test_state->push_back(test_in); test_sequence->push_back(test_state); my_adc->set_daq(*test_sequence); adc_results* resultat = dynamic_cast<adc_results*>(my_adc->get_samples(1)); FILE* outputFile = fopen("./out.txt","w"); int j; for(j = 0; j < 4*resultat->front()->samples; j += 4) { fprintf(outputFile, "%i\t%i\t%i\t%i\n", resultat->front()->data[j], resultat->front()->data[j+1], resultat->front()->data[j+2], resultat->front()->data[j+3]); } fclose(outputFile); delete my_adc; } catch(ADC_exception ae) { fprintf(stderr,"adc: %s\n",ae.c_str()); } }
static void alt_dequeue(FIBER_ALT *a) { FIBER_ALT_ARRAY *ar; unsigned int i; ar = channel_array(a->c, a->op); if (ar == NULL) acl_msg_fatal("%s(%d), %s: bad use of altdequeue op=%d", __FILE__, __LINE__, __FUNCTION__, a->op); for (i = 0; i < ar->n; i++) { if (ar->a[i] == a) { array_del(ar, i); return; } } acl_msg_fatal("%s(%d), %s: cannot find self in altdq", __FILE__, __LINE__, __FUNCTION__); }
static void alt_exec(FIBER_ALT *a) { FIBER_ALT_ARRAY *ar; FIBER_ALT *other; ACL_CHANNEL *c; int i; c = a->c; ar = channel_array(c, otherop(a->op)); if (ar && ar->n) { i = rand() % ar->n; other = ar->a[i]; alt_copy(a, other); alt_all_dequeue(other->xalt); other->xalt[0].xalt = other; acl_fiber_ready(other->fiber); } else alt_copy(a, NULL); }
static int alt_can_exec(FIBER_ALT *a) { FIBER_ALT_ARRAY *ar; ACL_CHANNEL *c; if (a->op == CHANNOP) return 0; c = a->c; if (c->bufsize == 0) { ar = channel_array(c, otherop(a->op)); return ar && ar->n; } switch (a->op) { default: return 0; case CHANSND: return c->nbuf < c->bufsize; case CHANRCV: return c->nbuf > 0; } }
SpectrumMI40xxSeries::SpectrumMI40xxSeries(const ttlout& t_line, float impedance, int ext_reference_clock) { // print neat string to inform the user fprintf(stderr, "Initializing ADC card\n"); // to be configured device_id=0; trigger_line=t_line; default_settings.qwSetChEnableMap = channel_array(ADC_MI_DEFAULT_CHANNELS); default_settings.lSetChannels = default_settings.qwSetChEnableMap.count(); default_settings.impedance = new double[default_settings.lSetChannels]; default_settings.sensitivity = new double[default_settings.lSetChannels]; default_settings.offset = new int[default_settings.lSetChannels]; for(int i = 0; i < default_settings.lSetChannels; i++) { default_settings.impedance[i] = ADC_MI_DEFAULT_IMPEDANCE; default_settings.sensitivity[i] = ADC_MI_DEFAULT_SENSITIVITY; // Set sensitivity in Volts to the default (maximum) value default_settings.offset[i] = ADC_MI_DEFAULT_OFFSET; // Set offsets in % of sensitivity to default (0) } default_settings.ext_reference_clock=ext_reference_clock; // Hz effective_settings=NULL; # if defined __linux__ // ----- open driver ----- deviceno = open ("/dev/spc0", O_RDWR); if (deviceno == -1) { std::string error_message="could not open /dev/spc0"; if (errno==0) throw SpectrumMI40xxSeries_error( error_message+" (unknown error)"); else throw SpectrumMI40xxSeries_error( error_message+" ("+strerror(errno)+")"); } # endif # if defined __CYGWIN__ // open library dll spectrum_driver_dll = LoadLibrary("spectrum.dll"); if (spectrum_driver_dll==NULL) throw SpectrumMI40xxSeries_error("could not open driver dll"); deviceno=0; // load driver functions # define load_spectrum_function(name) name = ( name##_type)GetProcAddress(spectrum_driver_dll, #name); \ if (name == NULL) { FreeLibrary(spectrum_driver_dll); \ throw SpectrumMI40xxSeries_error("failed to load function" #name "" ); \ } load_spectrum_function(SpcInitPCIBoards); load_spectrum_function(SpcGetParam); load_spectrum_function(SpcSetParam); load_spectrum_function(SpcGetData); // find spectrum boards boardcount=0; SpcInitPCIBoards(&boardcount,&PCIVersion); if (boardcount<=0) { FreeLibrary(spectrum_driver_dll); throw SpectrumMI40xxSeries_error("no spectrum boards found"); } # endif /* calculate the sample number that can be saved without fifo */ int memory_size=0; SpcGetParam(deviceno,SPC_PCIMEMSIZE,&memory_size); fifo_minimal_size=memory_size/(sizeof(short int)*2); /* get the device type */ SpcGetParam(deviceno, SPC_PCITYP, &cardType); if (cardType != TYP_MI4020 && cardType != TYP_MI4021 && cardType != TYP_MI4022 && cardType != TYP_MI4030 && cardType != TYP_MI4031 && cardType != TYP_MI4032) { throw SpectrumMI40xxSeries_error("Board type not supported"); } /* make a check, whether spectrum board is running */ int actual_status=0; SpcGetParam(deviceno, SPC_STATUS, &actual_status); if (actual_status!=SPC_READY) { fprintf(stderr, "Warning: Spectrum board was is running before reset.\n"); } #if SPC_DEBUG fprintf(stderr,"External reference clock: %i\n",default_settings.ext_reference_clock); #endif int ErrorOccurred=1; SpcSetParam(deviceno, SPC_COMMAND, SPC_RESET)==ERR_OK && // reset device first SpcSetParam (deviceno, SPC_GATE, 1)==ERR_OK && // Gated Triggering SpcSetParam (deviceno, SPC_PLL_ENABLE, 1)==ERR_OK && // Internal PLL enabled for clock SpcSetParam (deviceno, SPC_CLOCKOUT, 0)==ERR_OK && // No clock output SpcSetParam (deviceno, SPC_REFERENCECLOCK, default_settings.ext_reference_clock)==ERR_OK && // external reference clock SpcSetParam (deviceno, SPC_EXTERNALCLOCK, 0)==ERR_OK && // but no external sample clock SpcSetParam (deviceno, SPC_CLOCK50OHM, 0)==ERR_OK && // clock input NOT with 50Ohm impedance SpcSetParam (deviceno, SPC_TRIGGERMODE, TM_TTLPOS)==ERR_OK && // ttl trigger is used SpcSetParam (deviceno, SPC_TRIGGEROUT, 0)==ERR_OK && // No trigger output SpcSetParam (deviceno, SPC_TRIGGER50OHM, 0)==ERR_OK && // Trigger to 1MOhm, necessary for steep slopes (ErrorOccurred=0); // done, really no error occurred // ----- driver error: request error and end program ----- if (ErrorOccurred!=0) { int32 lErrorCode, lErrorReg, lErrorValue; SpcGetParam (deviceno, SPC_LASTERRORCODE, &lErrorCode); SpcGetParam (deviceno, SPC_LASTERRORREG, &lErrorReg); SpcGetParam (deviceno, SPC_LASTERRORVALUE, &lErrorValue); char error_message[256]; snprintf(error_message, sizeof(error_message),"Configuration error %d in register %d at value %d", lErrorCode, lErrorReg, lErrorValue); throw SpectrumMI40xxSeries_error(error_message); } /* print lines with useful information: */ fprintf(stderr, "Spectrum MI40xx series board with %d byte memory\n", memory_size); fprintf(stderr, " impedance set to %g Ohm\n expecting trigger on id=%d ttls=0x%lx\n external clock frequency set to %g Hz\n", impedance, t_line.id, t_line.ttls.to_ulong(), (float)ext_reference_clock ); }
void SpectrumMI40xxSeries::collect_config_recursive(state_sequent& exp, SpectrumMI40xxSeries::Configuration& settings) { /* start with dummy node */ DataManagementNode* new_branch=new DataManagementNode(NULL); DataManagementNode* where_to_append=new_branch; double parent_timeout=settings.timeout; settings.timeout=0.0; /* loop over all states and sequences */ for (state_sequent::iterator i=exp.begin(); i!=exp.end(); ++i) { state* a_state=dynamic_cast<state*>(*i); if (a_state==NULL) throw SpectrumMI40xxSeries_error("state_atom not expected in sate_sequent"); if (dynamic_cast<state_parallel*>(*i)!=NULL) throw SpectrumMI40xxSeries_error("state_parallel handling is not jet implemented"); state_sequent* a_sequence=dynamic_cast<state_sequent*>(a_state); if (a_sequence!=NULL) { // found a sequence DataManagementNode* tmp_structure=settings.data_structure; settings.data_structure=where_to_append; collect_config_recursive(*a_sequence, settings); settings.data_structure=tmp_structure; } /* end working on sequence */ else { // found a state, not a sequence settings.timeout+=a_state->length; #if SPC_DEBUG fprintf(stderr,"SETTINGS %e %e\n",settings.timeout,a_state->length); #endif // collect analogin sections in state std::list<analogin*> inputs; /* loop over all device definitions in a state */ state::iterator j=a_state->begin(); while (j!=a_state->end()) { analogin* input=dynamic_cast<analogin*>(*j); if (input!=NULL && input->id==device_id) { /* collect appropiate analogin sections, forget others */ if (input->samples<=0 || input->sample_frequency<=0) delete input; else inputs.push_back(input); j=a_state->erase(j); } else ++j; } if (!inputs.empty()) { /* evaluate the found analogin definitions */ if (inputs.size()>1) { while (!inputs.empty()) { delete inputs.front(); inputs.pop_front(); } throw ADC_exception("can not handle more than one analogin section per state"); } /* save sampling frequency */ if (settings.samplefreq<=0) settings.samplefreq=inputs.front()->sample_frequency; else if (settings.samplefreq != inputs.front()->sample_frequency) { while (!inputs.empty()) { delete inputs.front(); inputs.pop_front(); } throw ADC_exception("Sorry, but gated sampling requires same sampling frequency in all analogin sections"); } /* save channel mask and number of channels */ if (settings.lSetChannels > 0 && settings.qwSetChEnableMap.to_ulong() > 0) { if (settings.qwSetChEnableMap != inputs.front()->channels) { fprintf(stderr, "Warning! different channels enabled in input %lu and in config %lu, setting to default \n", settings.qwSetChEnableMap.to_ulong(), inputs.front()->channels.to_ulong()); settings.qwSetChEnableMap = channel_array(ADC_MI_DEFAULT_CHANNELS); settings.lSetChannels = settings.qwSetChEnableMap.count(); } } else { settings.qwSetChEnableMap = inputs.front()->channels; settings.lSetChannels = inputs.front()->nchannels; } /* save sensitivity */ if (settings.sensitivity != NULL) { // if sensitivity is set, make sure it's valid (i.e. the same for all inputs) for (int k = 0; k < inputs.front()->nchannels; k++) { if (settings.sensitivity[k] != inputs.front()->sensitivity[k]) { fprintf(stderr, "Warning! different sensitivity specified (here %f, elsewhere %f), choosing higher voltage\n", settings.sensitivity[k], inputs.front()->sensitivity[k]); if (settings.sensitivity[k] < inputs.front()->sensitivity[k]) { settings.sensitivity[k] = inputs.front()->sensitivity[k]; } } } } else { settings.sensitivity = inputs.front()->sensitivity; } // check if sensitivity is valid for (int k = 0; k < inputs.front()->nchannels; k++) { bool sensAllowed = false; for (int l = 0; l < ADC_MI_ALLOWED_SENSITIVITY_LENGTH; l++) { if (settings.sensitivity[k] == ADC_MI_ALLOWED_SENSITIVITY[l] ) { sensAllowed = true; break; } } if (!sensAllowed) { fprintf(stderr, "Warning! Illegal sensitivity specified for channel %i: %f", k, inputs.front()->sensitivity[k]); settings.sensitivity[k] = ADC_MI_DEFAULT_SENSITIVITY; } } /* save impedance */ if (settings.impedance != NULL) { for (int k = 0; k < inputs.front()->nchannels; k++) { if (settings.impedance[k] != inputs.front()->impedance[k]) { fprintf(stderr, "Warning! different impedance specified (here %f, elsewhere %f), setting to default\n", settings.impedance[k], inputs.front()->impedance[k]); settings.impedance[k] = ADC_MI_DEFAULT_IMPEDANCE; } if (settings.impedance[k] != ADC_MI_DEFAULT_IMPEDANCE && settings.impedance[k] != ADC_MI_ALLOWED_IMPEDANCE) { fprintf(stderr, "Warning! Illegal impedance specified for channel %i: %f",k, inputs.front()->impedance[k]); settings.offset[k] = 0; } } } else { settings.impedance = inputs.front()->impedance; } /* save offsets */ if (settings.offset != NULL) { for (int k = 0; k < inputs.front()->nchannels; k++) { if (settings.offset[k] != inputs.front()->offset[k]) { fprintf(stderr, "Warning! different impedance specified (here %i, elsewhere %i), setting to default\n", settings.offset[k], inputs.front()->offset[k]); settings.offset[k] = ADC_MI_DEFAULT_OFFSET; } if (inputs.front()->offset[k] > 100 || inputs.front()->offset[k] < -100) { fprintf(stderr, "Warning! Illegal offset specified for channel %i: %i", k, inputs.front()->offset[k]); settings.offset[k] = 0; } } } else { settings.offset = inputs.front()->offset; } if (inputs.front()->samples%4 != 0) { throw ADC_exception("Number of samples must be a multiple of four"); } // calculate the time required double delayed_gating_time=0.0; // the gating time has an offset, which was found to be 1.5 dwelltimes for <2.5MHz and 4.5 dwelltimes for >=2.5MHz double gating_time; #if SPC_DEBUG fprintf(stderr, "Channels: %lu\n", settings.qwSetChEnableMap.to_ulong()); #endif /* check if channel mask is legal for the card */ if (this->IsChannelMaskLegal(inputs.front()->channels.to_ulong())) { settings.qwSetChEnableMap = inputs.front()->channels; settings.lSetChannels = inputs.front()->nchannels; } else { throw SpectrumMI40xxSeries_error("Selected channels combination not allowed for this card type"); } /* apply proper timing */ if ( settings.qwSetChEnableMap.to_ulong()==(CHANNEL0|CHANNEL1) || settings.qwSetChEnableMap.to_ulong()==(CHANNEL0|CHANNEL1|CHANNEL2|CHANNEL3) ) { #if SPC_DEBUG fprintf(stderr, "Default Channels\n"); #endif if (settings.samplefreq<2.5e6) { // if sampling rate is <2.5MHz, there is another data handling mode, // see MI4021 manual page 79: "Accquisition Delay: -6 Samples" // it might be necessary to add 0.1 dwelltime to shift the sampling start a little more... // edit by Stefan Reutter @2013-06, it seems that the MI4021 cards actually have a second // threshold at 500 kHz that is not mentioned in the manual. // this can be tested by disabling the if below and switching over the threshold gating_time=(inputs.front()->samples)/settings.samplefreq; if (settings.samplefreq >= 5e5) { delayed_gating_time=ceil(1e8*6.0/settings.samplefreq)/1e8; } else { delayed_gating_time=0.0; } } else { gating_time=(inputs.front()->samples+3)/settings.samplefreq; delayed_gating_time=0.0; } } // disabled the more exotic channel setup as it is untested with the updated timings and probably not used anyways /* else if (settings.qwSetChEnableMap.to_ulong()==CHANNEL0 || settings.qwSetChEnableMap.to_ulong()==(CHANNEL0|CHANNEL2) ) { #if SPC_DEBUG fprintf(stderr, "Weird Channels\n"); #endif if (settings.samplefreq<5e6) { gating_time=(inputs.front()->samples+1.5)/settings.samplefreq; delayed_gating_time=ceil(1e8*6.0/settings.samplefreq)/1e8; } else { gating_time=(inputs.front()->samples+4.5)/settings.samplefreq; delayed_gating_time=-ceil(1e8*7.0/settings.samplefreq)/1e8; } */else { throw SpectrumMI40xxSeries_error("Selected channels combination not allowed"); } gating_time=ceil(1e8*gating_time)/1e8; double time_required=delayed_gating_time+gating_time; // check time requirements if (a_state->length < gating_time) { char parameter_info[512]; snprintf(parameter_info,sizeof(parameter_info), "(%" SIZETPRINTFLETTER " samples, %g samplerate, %e time required, %e state time)", inputs.front()->samples, settings.samplefreq, time_required, a_state->length); #if SPC_DEBUG fprintf(stderr, "state is shorter than acquisition time %e time required, %e state time\n", gating_time, a_state->length); #endif // update the state length if it's shorter than the gate. this is usually due to rounding to 10 ns for the pulseblaster if (ceil(1e8*a_state->length)/1e8 < time_required) { throw ADC_exception(std::string("state is shorter than acquisition time")+parameter_info); } else { a_state->length = time_required; } } // if necessary, add the gating pulse delay... if (delayed_gating_time>0.0) { state* delayed_gating_state=new state(*a_state); delayed_gating_state->length=delayed_gating_time; // insert before me exp.insert(i,(state_atom*)delayed_gating_state); } else if (delayed_gating_time < 0.0) { /* For +samples delays 1. get the previous state 2. if the length is not long enough (6*dw) add the state before 3. split the state(s) so that we have the gating on 6*dw before the actual recording */ double rest_length = delayed_gating_time; state_sequent::iterator i_prev; state* prev_state; i_prev = i; do { i_prev--; prev_state = dynamic_cast<state*>(*(i_prev)); rest_length -= prev_state->length; fprintf(stderr, "DW rest_length: %g\n", rest_length); fprintf(stderr, "DW state_length: %g\n", prev_state->length); if (rest_length >= 0) prev_state->push_back(trigger_line.copy_new()); // add trigger to this state else { // split final state state* prev_state_1 = prev_state->copy_flat(); //create copy of current state prev_state_1->length += rest_length; // adjust 1st part length exp.insert(i_prev,(state_atom*) prev_state_1); // insert AFTER prev_state prev_state->length = -rest_length; // adjust 2nd part length prev_state->push_back(trigger_line.copy_new()); // add trigger to 2nd part break; } } while (i_prev!=exp.begin() || rest_length > 0.0); } # if SPC_DEBUG fprintf(stderr, "sequence after pre_trigger correction:\n"); xml_state_writer().write_states(stderr, exp); # endif // adapt the pulse program for gated sampling if (a_state->length == gating_time) { // state has proper length a_state->push_back(trigger_line.copy_new()); } else { # if SPC_DEBUG fprintf(stderr, "state too long, length %e, time required %e\n", a_state->length, time_required); # endif // state is too long... // create new one with proper time and gated sampling pulse state* gated_sampling_pulse=new state(*a_state); gated_sampling_pulse->length=gating_time; gated_sampling_pulse->push_back(trigger_line.copy_new()); // insert gate pulse state before remaining (original) state exp.insert(i,(state_atom*)gated_sampling_pulse); // shorten this state a_state->length-=time_required; } # if SPC_DEBUG fprintf(stderr, "sequence after correcting trigger state:\n"); xml_state_writer().write_states(stderr, exp); # endif /* save sampleno */ DataManagementNode* new_one=new DataManagementNode(new_branch); new_one->n=inputs.front()->samples; new_one->child=NULL; new_one->next=where_to_append->next; where_to_append->next=new_one; where_to_append=new_one; while (!inputs.empty()) { delete inputs.front(); inputs.pop_front(); } } /* !inputs.empty() */ } /* end working on state */ } /* i */ /* something happened? */ if (new_branch->next!=NULL) { /* make dummy node to a loop */ new_branch->n=exp.repeat; new_branch->child=new_branch->next; /* if possible, append it */ if (settings.data_structure!=NULL) { new_branch->parent=settings.data_structure->parent; new_branch->next=settings.data_structure->next; settings.data_structure->next=new_branch; } else { new_branch->parent=NULL; new_branch->next=NULL; settings.data_structure=new_branch; } } else delete new_branch; settings.timeout*=exp.repeat; settings.timeout+=parent_timeout; #ifdef SPC_DEBUG fprintf(stderr,"setting.timout %g\n",settings.timeout); #endif return; }