Ejemplo n.º 1
0
static void alt_queue(FIBER_ALT *a)
{
	FIBER_ALT_ARRAY *ar;

	ar = channel_array(a->c, a->op);
	array_add(ar, a);
}
Ejemplo n.º 2
0
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());
	}
}
Ejemplo n.º 3
0
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__);
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
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;
}