Example #1
0
/** @brief Main processing function used to decimate and convert data signals.
 *
 * This function takes as argument raw FPGA signal and performs decimation and
 * conversion from ADC samples to voltage.
 * Output signals are of length SIGNAL_LENGTH (defined in main_osc.h), input 
 * signals are of length OSC_FPGA_SIG_LEN (defined in fpga_osc.h).
 *
 * @param [out] cha_signal - processed output signal for Channel A
 * @param [in] in_cha_signal - input raw signal for Channel A
 * @param [out] chb_signal - processed output signal for Channel B
 * @param [in] in_chb_signal - input raw signal for Channel B
 * @param [out] time_signal - processed output time vector signal 
 * @param [in] dec_factor - decimation factor parameter set by main or client
 * @param [in] t_start - starting time of requested acquisition
 * @param [in] t_stop - stopping time of requested acquisition
 * @param [in] time_unit - time units currently used
 *
 * @retval 0 Always returns 0.
*/
int rp_osc_decimate_with_calib(float **cha_signal, int *in_cha_signal,
                    float **chb_signal, int *in_chb_signal,
                    float **time_signal, int dec_factor, 
                    float t_start, float t_stop, int time_unit,
                    rp_osc_meas_res_t *ch1_meas, rp_osc_meas_res_t *ch2_meas,
                    float ch1_max_adc_v, float ch2_max_adc_v,
                    float ch1_user_dc_off, float ch2_user_dc_off)
{
    int t_start_idx, t_stop_idx;
    float smpl_period = c_osc_fpga_smpl_period * dec_factor;
    int   t_unit_factor = rp_osc_get_time_unit_factor(time_unit);
    int t_step;
    int in_idx, out_idx, t_idx;
    int wr_ptr_curr, wr_ptr_trig;

    float *cha_s = *cha_signal;
    float *chb_s = *chb_signal;
    float *t = *time_signal;
    
    /* If illegal take whole frame */
    if(t_stop <= t_start) {
        t_start = 0;
        t_stop = (OSC_FPGA_SIG_LEN-1) * smpl_period;
    }
    
    /* convert time to samples */
    t_start_idx = round(t_start / smpl_period);
    t_stop_idx  = round(t_stop / smpl_period);

    if((((t_stop_idx-t_start_idx)/(float)(SIGNAL_LENGTH-1))) < 1)
        t_step = 1;
    else {
        /* ceil was used already in rp_osc_main() for parameters, so we can easily
         * use round() here 
         */
        t_step = round((t_stop_idx-t_start_idx)/(float)(SIGNAL_LENGTH-1));
    }
    osc_fpga_get_wr_ptr(&wr_ptr_curr, &wr_ptr_trig);
    in_idx = wr_ptr_trig + t_start_idx - 3;

    if(in_idx < 0) 
        in_idx = OSC_FPGA_SIG_LEN + in_idx;
    if(in_idx >= OSC_FPGA_SIG_LEN)
        in_idx = in_idx % OSC_FPGA_SIG_LEN;

    /* First perform measurements on non-decimated signal:
     *  - min, max - performed in the loop
     *  - avg, amp - performed after the loop
     *  - freq, period - performed in the next decimation loop
     */
    for(out_idx=0; out_idx < OSC_FPGA_SIG_LEN; out_idx++) {
        rp_osc_meas_min_max(ch1_meas, in_cha_signal[out_idx]);
        rp_osc_meas_min_max(ch2_meas, in_chb_signal[out_idx]);
    }

    for(out_idx=0, t_idx=0; out_idx < SIGNAL_LENGTH; 
        out_idx++, in_idx+=t_step, t_idx+=t_step) {
        /* Wrap the pointer */
        if(in_idx >= OSC_FPGA_SIG_LEN)
            in_idx = in_idx % OSC_FPGA_SIG_LEN;

        cha_s[out_idx] = osc_fpga_cnv_cnt_to_v_with_calib(in_cha_signal[in_idx], ch1_max_adc_v,
                                               wrkr_rp_calib_params->fe_ch1_dc_offs,
                                               ch1_user_dc_off);

        chb_s[out_idx] = osc_fpga_cnv_cnt_to_v_with_calib(in_chb_signal[in_idx], ch2_max_adc_v,
                                               wrkr_rp_calib_params->fe_ch2_dc_offs,
                                               ch2_user_dc_off);

        t[out_idx] = (t_start + (t_idx * smpl_period)) * t_unit_factor;

        /* A bug in FPGA? - Trig & write pointers not sample-accurate. */
        if ( (dec_factor > 64) && (out_idx == 1) ) {
            int i;
            for (i=0; i < out_idx; i++) {
                cha_s[i] = cha_s[out_idx];
                chb_s[i] = chb_s[out_idx];
            }
        }
    }

    return 0;
}
Example #2
0
/*----------------------------------------------------------------------------------*/
int rp_osc_decimate_partial(float **cha_out_signal, int *cha_in_signal, 
                            float **chb_out_signal, int *chb_in_signal,
                            float **time_out_signal, int *next_wr_ptr, 
                            int last_wr_ptr, int step_wr_ptr, int next_out_idx,
                            float t_start, int dec_factor, int time_unit,
                            rp_osc_meas_res_t *ch1_meas, 
                            rp_osc_meas_res_t *ch2_meas,
                            float ch1_max_adc_v, float ch2_max_adc_v,
                            float ch1_user_dc_off, float ch2_user_dc_off)
{
    float *cha_out = *cha_out_signal;
    float *chb_out = *chb_out_signal;
    float *t_out   = *time_out_signal;
    int    in_idx = *next_wr_ptr;

    float smpl_period = c_osc_fpga_smpl_period * dec_factor;
    int   t_unit_factor = rp_osc_get_time_unit_factor(time_unit);

    int curr_ptr;
    /* check if we have reached currently acquired signals in FPGA */
    osc_fpga_get_wr_ptr(&curr_ptr, NULL);

    for(; in_idx < curr_ptr; in_idx++) {
        if(in_idx >= OSC_FPGA_SIG_LEN)
            in_idx = in_idx % OSC_FPGA_SIG_LEN;
        rp_osc_meas_min_max(ch1_meas, cha_in_signal[in_idx]);
        rp_osc_meas_min_max(ch2_meas, chb_in_signal[in_idx]);
    }

    in_idx = *next_wr_ptr;

    for(; (next_out_idx < ((int)rp_get_params_bode(5))); next_out_idx++, 
            in_idx += step_wr_ptr) {
        int curr_ptr;
        int diff_ptr;
        /* check if we have reached currently acquired signals in FPGA */
        osc_fpga_get_wr_ptr(&curr_ptr, NULL);
        if(in_idx >= OSC_FPGA_SIG_LEN)
            in_idx = in_idx % OSC_FPGA_SIG_LEN;
        diff_ptr = (in_idx-curr_ptr);
        /* Check that we did not hit the curr ptr (and that pointer is not
         * wrapped 
         */
        if((in_idx >= curr_ptr) && (diff_ptr > 0) && (diff_ptr < 100))
            break;

        cha_out[next_out_idx] = 
            osc_fpga_cnv_cnt_to_v(cha_in_signal[in_idx], ch1_max_adc_v,
                                  rp_calib_params->fe_ch1_dc_offs,
                                  ch1_user_dc_off);

        chb_out[next_out_idx] = 
            osc_fpga_cnv_cnt_to_v(chb_in_signal[in_idx], ch2_max_adc_v,
                                  rp_calib_params->fe_ch1_dc_offs,
                                  ch2_user_dc_off);

        t_out[next_out_idx]   = 
            (t_start + ((next_out_idx*step_wr_ptr)*smpl_period))*t_unit_factor;

        /* A bug in FPGA? - Trig & write pointers not sample-accurate. */
        if ( (dec_factor > 64) && (next_out_idx == 2) ) {
             int i;
             for (i=0; i < next_out_idx; i++) {
                 cha_out[i] = cha_out[next_out_idx];
                 chb_out[i] = chb_out[next_out_idx];
             }
         }
    }

    *next_wr_ptr = in_idx;

    return next_out_idx;
}