/** @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; }
/*----------------------------------------------------------------------------------*/ 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; }