예제 #1
0
파일: spec_fpga.c 프로젝트: Gulzt/RedPitaya
int spectr_fpga_update_params(int trig_imm, int trig_source, int trig_edge, 
                           float trig_delay, float trig_level, int freq_range,
                           int enable_avg_at_dec)
{	
    /* TODO: Locking of memory map */
    int fpga_trig_source = spectr_fpga_cnv_trig_source(trig_imm, trig_source, 
                                                    trig_edge);
    int fpga_dec_factor = spectr_fpga_cnv_freq_range_to_dec(freq_range);
	fprintf(stderr, "freq_range = %d fpga_dec_factor = %d\n", freq_range, fpga_dec_factor);
    int fpga_delay;
    int fpga_trig_thr = spectr_fpga_cnv_v_to_cnt(trig_level);

    /* Equalization filter coefficients */
    uint32_t gain_hi_cha_filt_aa = 0x7D93;
    uint32_t gain_hi_cha_filt_bb = 0x437C7;
    uint32_t gain_hi_cha_filt_pp = 0x0;
    uint32_t gain_hi_cha_filt_kk = 0xffffff;
    
    uint32_t gain_hi_chb_filt_aa = 0x7D93;
    uint32_t gain_hi_chb_filt_bb = 0x437C7;
    uint32_t gain_hi_chb_filt_pp = 0x0;
    uint32_t gain_hi_chb_filt_kk = 0xffffff;
    
    if((fpga_trig_source < 0) || (fpga_dec_factor < 0)) {
        fprintf(stderr, "spectr_fpga_update_params() failed\n");
        return -1;
    }

    fpga_delay = SPECTR_FPGA_SIG_LEN - 3;

    /* Trig source is written after ARM */
    /*    g_spectr_fpga_reg_mem->trig_source   = fpga_trig_source;*/
    if(trig_source == 0) 
        g_spectr_fpga_reg_mem->cha_thr   = fpga_trig_thr;
    else
        g_spectr_fpga_reg_mem->chb_thr   = fpga_trig_thr;

    g_spectr_fpga_reg_mem->data_dec      = fpga_dec_factor;
    g_spectr_fpga_reg_mem->trigger_delay = (uint32_t)fpga_delay;

    g_spectr_fpga_reg_mem->other = enable_avg_at_dec;

    g_spectr_fpga_reg_mem->cha_filt_aa = gain_hi_cha_filt_aa;
    g_spectr_fpga_reg_mem->cha_filt_bb = gain_hi_cha_filt_bb;
    g_spectr_fpga_reg_mem->cha_filt_pp = gain_hi_cha_filt_pp;
    g_spectr_fpga_reg_mem->cha_filt_kk = gain_hi_cha_filt_kk;

    g_spectr_fpga_reg_mem->chb_filt_aa = gain_hi_chb_filt_aa;
    g_spectr_fpga_reg_mem->chb_filt_bb = gain_hi_chb_filt_bb;
    g_spectr_fpga_reg_mem->chb_filt_pp = gain_hi_chb_filt_pp;
    g_spectr_fpga_reg_mem->chb_filt_kk = gain_hi_chb_filt_kk;

    return 0;
}
예제 #2
0
파일: dsp.c 프로젝트: 1nfused/RedPitaya
int rp_resp_prepare_freq_vector(float **freq_out, double f_s,
                                float freq_range, int II, int JJ, int k1, int kstp)
{
    int i;
    float *f = *freq_out;

    float unit_div = 1e6;

    float freq_smpl = f_s / (float)spectr_fpga_cnv_freq_range_to_dec(freq_range);

    if(!f) {
        fprintf(stderr, "rp_spectr_prepare_freq_vector() not initialized\n");
        return -1;
    }

    switch(spectr_fpga_cnv_freq_range_to_unit(freq_range)) {
    case 2:
        unit_div = 1e6;
        break;
    case 1:
        unit_div = 1e3;
        break;
    case 0:
        unit_div = 1;
        break;
    default:
        fprintf(stderr, "rp_spectr_prepare_freq_vector() wrong freq_range\n");
        return -1;
    }

    for (i = 0;i < II*JJ; i++) {
        f[i] = ((float) (k1+ i *kstp )) * (float) freq_smpl / ((float) SPECTR_FPGA_SIG_LEN)/ unit_div;
    }

    if (II*JJ < SPECTR_OUT_SIG_LEN) {
        for (i = II*JJ; i < SPECTR_OUT_SIG_LEN; i++)
            f[i] = f[II*JJ - 1];
    }

    return 0;
}
예제 #3
0
파일: worker.c 프로젝트: 1nfused/RedPitaya
void *rp_spectr_worker_thread(void *args)
{
    rp_spectr_worker_state_t old_state, state;
    rp_app_params_t          curr_params[PARAMS_NUM];
    int                      fpga_update = 1;
    int                      params_dirty = 1;

    // TODO: Name these
    int jj_state = 0;
    int iix, iix2;
    int cal_butt1_old, cal_butt2_old;
    int start_state = 1;
    awg_param_t awg_par;

    pthread_mutex_lock(&rp_spectr_ctrl_mutex);
    old_state = state = rp_spectr_ctrl;
    pthread_mutex_unlock(&rp_spectr_ctrl_mutex);

    while(1) {
        /* update states - we save also old state to see if we need to reset
         * FPGA 
         */
        old_state = state;
        pthread_mutex_lock(&rp_spectr_ctrl_mutex);
        state = rp_spectr_ctrl;
        if(rp_spectr_params_dirty) {
            memcpy(&curr_params, &rp_spectr_params, 
                   sizeof(rp_app_params_t)*PARAMS_NUM);
            fpga_update = rp_spectr_params_fpga_update;
            rp_spectr_params_dirty = 0;
        }
        pthread_mutex_unlock(&rp_spectr_ctrl_mutex);

        /* request to stop worker thread, we will shut down */
        if(state == rp_spectr_quit_state) {
            return 0;
        }

        if(fpga_update) {
            spectr_fpga_reset();
            //cal_ready1 = 0; // Resets calibration
            //cal_ready2 = 0; // Resets calibration
            jj_state = 0;

            if(spectr_fpga_update_params(0, 0, 0, 0, 0, 
                    (int)curr_params[FREQ_RANGE_PARAM].value, 0) < 0) {
                rp_spectr_worker_change_state(rp_spectr_auto_state);
            }

            fpga_update = 0;
        }

        if(state == rp_spectr_idle_state) {
            usleep(10000);
            continue;
        }

        /* Prepare AWG data buffer  */
        // Buffer prepared only once in order to save CPU resources
        if (synth_ready == 0) {
            // Before preparing buffer visualize some constant signal
            rp_resp_init_sigs(&rp_tmp_signals[0], (float **)&rp_tmp_signals[1], (float **)&rp_tmp_signals[2]);
            rp_spectr_set_signals(rp_tmp_signals);

            for (iix2 = 0; iix2 < JJ; iix2++) {
                synthesize_fra_sig(dacamp,  iix2*II*kstp, kstp, II, ch1_data, iix2*NN, &tmpdouble, &awg_par);
                scale[iix2] = tmpdouble;
            }
            synth_ready = 1;
        }

        if (start_state == 0) {
            if (round(curr_params[EN_CAL_1].value) != cal_butt1_old) {
                cal_ready1 = 0;
            }
            if (round(curr_params[EN_CAL_2].value) != cal_butt2_old) {
                cal_ready2 = 0;
            }
        } else {
            start_state = 0;
            // The calibration consists in coping the current response data to reference cal. vectors
            for (iix = 0; iix < SPECTR_OUT_SIG_LEN; iix++) {
                rp_cha_resp_cal[iix] = 56e6;
                rp_chb_resp_cal[iix] = 56e6;
            }
        }

        cal_butt1_old = round(curr_params[EN_CAL_1].value);
        cal_butt2_old = round(curr_params[EN_CAL_2].value);

        // TODO: Implement signal generator part as a separate module

        /* Write the data to the FPGA and set FPGA AWG state machine for current pattern*/
        write_data_fpga(0, 1, 0,
                ch1_data, jj_state*NN,
                &awg_par, round(65536 /
                        ((float)spectr_fpga_cnv_freq_range_to_dec(curr_params[FREQ_RANGE_PARAM].value))));

        write_data_fpga(1, 1, 0,
                ch1_data, jj_state*NN,
                &awg_par, round(65536 /
                        ((float)spectr_fpga_cnv_freq_range_to_dec(curr_params[FREQ_RANGE_PARAM].value))));

        /* Start the writing machine: DATA ACQUISITION */
        spectr_fpga_arm_trigger();
        
        usleep(10);

        spectr_fpga_set_trigger(1);

        /* start working */
        pthread_mutex_lock(&rp_spectr_ctrl_mutex);
        old_state = state = rp_spectr_ctrl;
        pthread_mutex_unlock(&rp_spectr_ctrl_mutex);
        if((state == rp_spectr_idle_state) || (state == rp_spectr_abort_state)) {
            continue;
        } else if(state == rp_spectr_quit_state) {
            break;
        }

        /* polling until data is ready */
        while(1) {
            pthread_mutex_lock(&rp_spectr_ctrl_mutex);
            state = rp_spectr_ctrl;
            params_dirty = rp_spectr_params_dirty;
            pthread_mutex_unlock(&rp_spectr_ctrl_mutex);
            /* change in state, abort polling */
            if((state != old_state) || params_dirty) {
                break;
            }
                
            if(spectr_fpga_triggered()) {
                break;
            }
        }

        if((state != old_state) || params_dirty) {
            params_dirty = 0;
            continue;
        }

        /* retrieve data and process it*/
        spectr_fpga_get_signal(&rp_cha_in, &rp_chb_in);

        /* Calculate response at frequency components for each excitation pattern*/
        rp_resp_calc(&rp_cha_in[0], &rp_chb_in[0], jj_state*II, scale[jj_state], kstp, II, (double **)&rp_cha_resp, (double **)&rp_chb_resp);

        // Continue acquiring and processing until all the pattern sequence completed
        if (jj_state < JJ) {
            jj_state++;
        } else {
            // Response characterization completed
            jj_state = 0;

            /* Perform calibration at startup or parameter update.
             * TODO: add a GUI Calibration button for individual channels
             */
            if (cal_ready1 == 0)
            {																		// Provide calibration vector initialization since calibration
                cal_ready1 = 1;													    // executed on demand
                // The calibration consists in coping the current response data to reference cal. vectors
                for (iix = 0; iix < SPECTR_OUT_SIG_LEN; iix++) {
                    rp_cha_resp_cal[iix] = rp_cha_resp[iix];
                }
            }
            /* Perform calibration at startup or parameter update
             * TODO: add a GUI Calibration button for individual channels
             */
            if (cal_ready2 == 0)
            {																		// Provide calibration vector initialization since calibration
                cal_ready2 = 1;													    // executed on demand
                // The calibration consists in coping the current response data to reverence cal. vectors
                for (iix = 0; iix < SPECTR_OUT_SIG_LEN; iix++) {
                    rp_chb_resp_cal[iix] = rp_chb_resp[iix];
                }
            }

            // Calculate frequency vector for the frequencies where response measured
            rp_resp_prepare_freq_vector(&rp_tmp_signals[0],
                    c_spectr_fpga_smpl_freq,
                    curr_params[FREQ_RANGE_PARAM].value, II, JJ, k1, kstp);


            // Calculate frequency response in dB and implement calibration
            rp_resp_cnv_to_dB(&rp_cha_resp[0], &rp_chb_resp[0],
                    &rp_cha_resp_cal[0], &rp_chb_resp_cal[0],
                    (float **)&rp_tmp_signals[1],
                    (float **)&rp_tmp_signals[2], II*JJ);

            rp_spectr_set_signals(rp_tmp_signals);

            usleep(10000);

        }
    }

    return 0;
}