/*----------------------------------------------------------------------------------*/ int rp_osc_auto_set(rp_app_params_t *orig_params, float ch1_max_adc_v, float ch2_max_adc_v, float ch1_user_dc_off, float ch2_user_dc_off, int ch1_probe_att, int ch2_probe_att, int ch1_gain, int ch2_gain, int en_avg_at_dec) { const int c_noise_thr = 500; /* noise threshold */ rp_osc_worker_state_t old_state, state; int params_dirty; /* Min/maxes from both channel */ int max_cha = INT_MIN; int max_chb = INT_MIN; int min_cha = INT_MAX; int min_chb = INT_MAX; /* Y axis deltas, 0 - ChA, 1 - Chb */ int dy[2] = { 0, 0 }; int old_dy[2] = { 0, 0 }; /* Channel to be used for auto-algorithm: * 0 - Channel A * 1 - Channel B */ int channel; int smpl_cnt; int iter; int time_range = 0; for (iter=0; iter < 10; iter++) { /* 10 auto-trigger acquisitions */ pthread_mutex_lock(&rp_osc_ctrl_mutex); old_state = state = rp_osc_ctrl; pthread_mutex_unlock(&rp_osc_ctrl_mutex); osc_fpga_reset(); osc_fpga_update_params(1, 0, 0, 0, 0, time_range, ch1_max_adc_v, ch2_max_adc_v, rp_calib_params->fe_ch1_dc_offs, 0, rp_calib_params->fe_ch2_dc_offs, 0, ch1_probe_att, ch2_probe_att, ch1_gain, ch2_gain, 0); /* ARM & Trigger */ osc_fpga_arm_trigger(); osc_fpga_set_trigger(1); /* Wait for trigger to finish */ while(1) { pthread_mutex_lock(&rp_osc_ctrl_mutex); state = rp_osc_ctrl; params_dirty = rp_osc_params_dirty; pthread_mutex_unlock(&rp_osc_ctrl_mutex); /* change in state, abort polling */ if((state != old_state) || params_dirty) { return -1; } if(osc_fpga_triggered()) { break; } usleep(500); } /* Get the signals - available at rp_fpga_chX_signal vectors */ for(smpl_cnt = 0; smpl_cnt < OSC_FPGA_SIG_LEN; smpl_cnt++) { int cha_smpl = rp_fpga_cha_signal[smpl_cnt]; int chb_smpl = rp_fpga_chb_signal[smpl_cnt]; // TWO'S COMPLEMENT if(cha_smpl & (1<<(c_osc_fpga_adc_bits-1))) cha_smpl = -1 * ((cha_smpl ^ ((1<<c_osc_fpga_adc_bits)-1))+1); if(chb_smpl & (1<<(c_osc_fpga_adc_bits-1))) chb_smpl = -1 * ((chb_smpl ^ ((1<<c_osc_fpga_adc_bits)-1))+1); cha_smpl = cha_smpl + rp_calib_params->fe_ch1_dc_offs; chb_smpl = chb_smpl + rp_calib_params->fe_ch2_dc_offs; /* Get min/maxes */ max_cha = (max_cha < cha_smpl) ? cha_smpl : max_cha; min_cha = (min_cha > cha_smpl) ? cha_smpl : min_cha; max_chb = (max_chb < chb_smpl) ? chb_smpl : max_chb; min_chb = (min_chb > chb_smpl) ? chb_smpl : min_chb; } dy[0] = max_cha - min_cha; dy[1] = max_chb - min_chb; /* Calculate ratios of last amplitude increase for both channels */ const float c_inc_thr = 1.1; float ratio[2] = { 1e6, 1e6 }; int i; for(i = 0; i < 2; i++) { if (old_dy[i] != 0) { ratio[i] = (float)dy[i] / (float)old_dy[i]; } } old_dy[0] = dy[0]; old_dy[1] = dy[1]; /* Signal amplitude found & stable? */ if ( ((ratio[0] < c_inc_thr) && (dy[0] > c_noise_thr)) || ((ratio[1] < c_inc_thr) && (dy[1] > c_noise_thr)) ) { /* This is meant for optimizing the time it takes for AUTO to complete, * and is a compromise between the speed and robustness of the AUTO * algorithm. * Since it is fast enough, it is safer to search for amplitude through * all the iterations instead of bailing out sooner. */ //break; } /* Still searching? - Increase time range up to 130 ms (D = 1024). */ if ((iter % 3) == 2) { time_range++; if (time_range > 3) { time_range = 3; } } } /* Check the Y axis amplitude on both channels and select the channel with * the larger one. */ channel = (dy[0] > dy[1]) ? 0 : 1; if(dy[channel] < c_noise_thr) { /* No signal detected, set the parameters to: * - no decimation (time range 130 [us]) * - trigger mode - auto * - X axis - full, from 0 to 130 [us] * - Y axis - Min/Max + adding extra 200% to average */ TRACE("AUTO: No signal detected.\n"); int min_y, max_y, ave_y; orig_params[TRIG_MODE_PARAM].value = 0; orig_params[MIN_GUI_PARAM].value = 0; orig_params[MAX_GUI_PARAM].value = 130; orig_params[TIME_RANGE_PARAM].value = 0; orig_params[TRIG_SRC_PARAM].value = 0; orig_params[TRIG_LEVEL_PARAM].value = 0; orig_params[AUTO_FLAG_PARAM].value = 0; orig_params[TIME_UNIT_PARAM].value = 0; orig_params[TRIG_DLY_PARAM].value = 0; min_y = (min_cha < min_chb) ? min_cha : min_chb; max_y = (max_cha > max_chb) ? max_cha : max_chb; ave_y = (min_y + max_y) >> 1; min_y = (min_y - ave_y) * 2 + ave_y; max_y = (max_y - ave_y) * 2 + ave_y; orig_params[MIN_Y_NORM].value = min_y / (float)(1 << (c_osc_fpga_adc_bits - 1)); orig_params[MAX_Y_NORM].value = max_y / (float)(1 << (c_osc_fpga_adc_bits - 1)); // For POST response ... transform_to_iface_units(orig_params); return 0; } else {
/** @brief Main worker thread function. * * This is main worker thread function which implements continuous loop. This * loop is controlled with the state variable. This function should not be called * directly but with POSIX thread functions. * * @param [in] args Optinal arguments as defined by pthread API functions. * */ void *rp_osc_worker_thread(void *args) { rp_osc_worker_state_t old_state, state; rp_osc_params_t curr_params[PARAMS_NUM]; int fpga_update = 0; int dec_factor = 0; int time_vect_update = 0; uint32_t trig_source = 0; int params_dirty = 0; rp_osc_meas_res_t ch1_meas, ch2_meas; float ch1_max_adc_v = 1, ch2_max_adc_v = 1; if (wrkr_rp_calib_params != NULL) { ch1_max_adc_v = osc_fpga_calc_adc_max_v(wrkr_rp_calib_params->fe_ch1_fs_g_hi, 0); ch2_max_adc_v = osc_fpga_calc_adc_max_v(wrkr_rp_calib_params->fe_ch2_fs_g_hi, 0); } pthread_mutex_lock(&rp_osc_ctrl_mutex); old_state = state = rp_osc_ctrl; pthread_mutex_unlock(&rp_osc_ctrl_mutex); /* Continuous thread loop (exited only with 'quit' state) */ while(1) { /* update states - we save also old state to see if we need to reset * FPGA */ old_state = state; pthread_mutex_lock(&rp_osc_ctrl_mutex); state = rp_osc_ctrl; if(rp_osc_params_dirty) { memcpy(&curr_params, &rp_osc_params, sizeof(rp_osc_params_t)*PARAMS_NUM); fpga_update = rp_osc_params_fpga_update; rp_osc_params_dirty = 0; dec_factor = osc_fpga_cnv_time_range_to_dec(curr_params[TIME_RANGE_PARAM].value); time_vect_update = 1; } pthread_mutex_unlock(&rp_osc_ctrl_mutex); /* request to stop worker thread, we will shut down */ if(state == rp_osc_quit_state) { return 0; } if(fpga_update) { osc_fpga_reset(); if(osc_fpga_update_params((curr_params[TRIG_MODE_PARAM].value == 0), curr_params[TRIG_SRC_PARAM].value, curr_params[TRIG_EDGE_PARAM].value, /* Here we could use trigger, but it is safer * to use start GUI value (it was recalculated * correctly already in rp_osc_main() so we * can use it and be sure that all signal * (even if extended becuase of decimation * will be covered in the acquisition */ /*curr_params[TRIG_DLY_PARAM].value,*/ curr_params[MIN_GUI_PARAM].value, curr_params[TRIG_LEVEL_PARAM].value, curr_params[TIME_RANGE_PARAM].value, curr_params[EQUAL_FILT_PARAM].value, curr_params[SHAPE_FILT_PARAM].value, curr_params[GAIN1_PARAM].value, curr_params[GAIN2_PARAM].value) < 0) { fprintf(stderr, "Setting of FPGA registers failed\n"); rp_osc_worker_change_state(rp_osc_idle_state); } trig_source = osc_fpga_cnv_trig_source( (curr_params[TRIG_MODE_PARAM].value == 0), curr_params[TRIG_SRC_PARAM].value, curr_params[TRIG_EDGE_PARAM].value); fpga_update = 0; } if(state == rp_osc_idle_state) { usleep(10000); continue; } if(time_vect_update) { rp_osc_prepare_time_vector((float **)&rp_tmp_signals[0], dec_factor, curr_params[MIN_GUI_PARAM].value, curr_params[MAX_GUI_PARAM].value, curr_params[TIME_UNIT_PARAM].value); time_vect_update = 0; } /* Start new acquisition only if it is the index 0 (new acquisition) */ float time_delay = curr_params[TRIG_DLY_PARAM].value; /* Start the writting machine */ osc_fpga_arm_trigger(); /* Be sure to have enough time to load necessary history - wait */ if(time_delay < 0) { /* time delay is always in seconds - convert to [us] and * sleep */ usleep(round(-1 * time_delay * 1e6)); } else { usleep(1); } /* Start the trigger */ osc_fpga_set_trigger(trig_source); /* start working */ pthread_mutex_lock(&rp_osc_ctrl_mutex); old_state = state = rp_osc_ctrl; pthread_mutex_unlock(&rp_osc_ctrl_mutex); if((state == rp_osc_idle_state) || (state == rp_osc_abort_state)) { continue; } else if(state == rp_osc_quit_state) { break; } /* polling until data is ready */ while(1) { pthread_mutex_lock(&rp_osc_ctrl_mutex); state = rp_osc_ctrl; params_dirty = rp_osc_params_dirty; pthread_mutex_unlock(&rp_osc_ctrl_mutex); /* change in state, abort polling */ if((state != old_state) || params_dirty) { break; } if(osc_fpga_triggered()) { break; } usleep(1000); } if((state != old_state) || params_dirty) { params_dirty = 0; continue; } pthread_mutex_lock(&rp_osc_ctrl_mutex); state = rp_osc_ctrl; params_dirty = rp_osc_params_dirty; pthread_mutex_unlock(&rp_osc_ctrl_mutex); if((state != old_state) || params_dirty) continue; /* Triggered, decimate & convert the values */ if (wrkr_rp_calib_params != NULL) { rp_osc_meas_clear(&ch1_meas); rp_osc_meas_clear(&ch2_meas); //printf("ch1_max_adc_v=%f\n", ch1_max_adc_v); //printf("curr_params[GEN_DC_OFFS_1].value=%f\n", curr_params[GEN_DC_OFFS_1].value); rp_osc_decimate_with_calib((float **)&rp_tmp_signals[1], &rp_fpga_cha_signal[0], (float **)&rp_tmp_signals[2], &rp_fpga_chb_signal[0], (float **)&rp_tmp_signals[0], dec_factor, curr_params[MIN_GUI_PARAM].value, curr_params[MAX_GUI_PARAM].value, curr_params[TIME_UNIT_PARAM].value, &ch1_meas, &ch2_meas, ch1_max_adc_v, ch2_max_adc_v, curr_params[GEN_DC_OFFS_1].value, curr_params[GEN_DC_OFFS_2].value); } else { rp_osc_decimate((float **)&rp_tmp_signals[1], &rp_fpga_cha_signal[0], (float **)&rp_tmp_signals[2], &rp_fpga_chb_signal[0], (float **)&rp_tmp_signals[0], dec_factor, curr_params[MIN_GUI_PARAM].value, curr_params[MAX_GUI_PARAM].value, curr_params[TIME_UNIT_PARAM].value); } /* check again for change of state */ pthread_mutex_lock(&rp_osc_ctrl_mutex); state = rp_osc_ctrl; pthread_mutex_unlock(&rp_osc_ctrl_mutex); /* We have acquisition - if we are in single put state machine * to idle */ if((state == rp_osc_single_state) ) { rp_osc_worker_change_state(rp_osc_idle_state); } rp_osc_set_signals(rp_tmp_signals, SIGNAL_LENGTH-1); /* do not loop too fast */ usleep(10000); } return 0; }
/* Main worker thread */ void *rp_osc_worker_thread(void *args) { rp_osc_worker_state_t old_state, state; rp_app_params_t *curr_params = NULL; int fpga_update = 0; int dec_factor = 0; int time_vect_update = 0; uint32_t trig_source = 0; int params_dirty = 0; /* Long acquisition special function */ int long_acq = 0; /* long_acq if acq_time > 1 [s] */ int long_acq_idx = 0; int long_acq_first_wr_ptr = 0; int long_acq_last_wr_ptr = 0; int long_acq_step = 0; int long_acq_init_trig_ptr; rp_osc_meas_res_t ch1_meas, ch2_meas; float ch1_max_adc_v = 1, ch2_max_adc_v = 1; float max_adc_norm = osc_fpga_calc_adc_max_v(rp_calib_params->fe_ch1_fs_g_hi, 0); pthread_mutex_lock(&rp_osc_ctrl_mutex); old_state = state = rp_osc_ctrl; pthread_mutex_unlock(&rp_osc_ctrl_mutex); while(1) { /* update states - we also save old state to see if we need to reset * FPGA */ int start_measure = rp_get_params_bode(0); if(start_measure == 1){ char command[100]; float read_amp = rp_get_params_bode(1); float read_avg = rp_get_params_bode(2); float read_dc_bias = rp_get_params_bode(3); float read_start_freq = rp_get_params_bode(4); float read_counts = rp_get_params_bode(5); float read_scale = rp_get_params_bode(6); float read_end_freq = rp_get_params_bode(9); char amp[5]; char avg[5]; char dc_bias[5]; char s_freq[20]; char e_freq[20]; char scale[5]; char counts[5]; snprintf(amp, 5, "%f", read_amp); snprintf(avg, 5, "%f", read_avg); snprintf(dc_bias, 5, "%f", read_dc_bias); snprintf(s_freq, 20, "%f", read_start_freq); snprintf(e_freq,20, "%f", read_end_freq); snprintf(scale, 5, "%f", read_scale); snprintf(counts, 5, "%f", read_counts); strcpy(command, "/opt/www/apps/bode_plotter/bode 1 "); strcat(command, amp); strcat(command, " "); strcat(command, dc_bias); strcat(command, " "); strcat(command, avg); strcat(command, " "); strcat(command, counts); strcat(command, " "); strcat(command, s_freq); strcat(command, " "); strcat(command, e_freq); strcat(command, " "); strcat(command, scale); system(command); rp_set_params_bode(0, 0); } old_state = state; pthread_mutex_lock(&rp_osc_ctrl_mutex); state = rp_osc_ctrl; /* If there are no new params */ if(rp_osc_params_dirty) { rp_copy_params(rp_osc_params, (rp_app_params_t **)&curr_params); fpga_update = rp_osc_params_fpga_update; rp_osc_params_dirty = 0; dec_factor = osc_fpga_cnv_time_range_to_dec(curr_params[TIME_RANGE_PARAM].value); time_vect_update = 1; uint32_t fe_fsg1 = (curr_params[GAIN_CH1].value == 0) ? rp_calib_params->fe_ch1_fs_g_hi : rp_calib_params->fe_ch1_fs_g_lo; ch1_max_adc_v = osc_fpga_calc_adc_max_v(fe_fsg1, (int)curr_params[PRB_ATT_CH1].value); uint32_t fe_fsg2 = (curr_params[GAIN_CH2].value == 0) ? rp_calib_params->fe_ch2_fs_g_hi : rp_calib_params->fe_ch2_fs_g_lo; ch2_max_adc_v = osc_fpga_calc_adc_max_v(fe_fsg2, (int)curr_params[PRB_ATT_CH2].value); } pthread_mutex_unlock(&rp_osc_ctrl_mutex); /* request to stop worker thread, we will shut down */ if(state == rp_osc_quit_state) { rp_clean_params(curr_params); return 0; } if(state == rp_osc_auto_set_state) { /* Auto-set algorithm was selected - run it */ rp_osc_auto_set(curr_params, ch1_max_adc_v, ch2_max_adc_v, curr_params[GEN_DC_OFFS_1].value, curr_params[GEN_DC_OFFS_2].value, curr_params[PRB_ATT_CH1].value, curr_params[PRB_ATT_CH2].value, curr_params[GAIN_CH1].value, curr_params[GAIN_CH2].value, curr_params[EN_AVG_AT_DEC].value); /* Return calculated parameters to main module */ rp_update_main_params(curr_params); /* while(1) - loop until break */ continue; } if(fpga_update) { /* Reset write state machine? LG */ osc_fpga_reset(); if(osc_fpga_update_params((curr_params[TRIG_MODE_PARAM].value == 0), curr_params[TRIG_SRC_PARAM].value, curr_params[TRIG_EDGE_PARAM].value, /* Here we could use trigger, but it is safer * to use start GUI value (it was recalculated * correctly already in rp_osc_main() so we * can use it and be sure that all signal * (even if extended because of decimation * will be covered in the acquisition */ /*curr_params[TRIG_DLY_PARAM].value,*/ curr_params[MIN_GUI_PARAM].value, curr_params[TRIG_LEVEL_PARAM].value, curr_params[TIME_RANGE_PARAM].value, max_adc_norm, max_adc_norm, rp_calib_params->fe_ch1_dc_offs, curr_params[GEN_DC_OFFS_1].value, rp_calib_params->fe_ch2_dc_offs, curr_params[GEN_DC_OFFS_2].value, curr_params[PRB_ATT_CH1].value, curr_params[PRB_ATT_CH2].value, curr_params[GAIN_CH1].value, curr_params[GAIN_CH2].value, curr_params[EN_AVG_AT_DEC].value) < 0) { fprintf(stderr, "Setting of FPGA registers failed\n"); rp_osc_worker_change_state(rp_osc_idle_state); } trig_source = osc_fpga_cnv_trig_source( (curr_params[TRIG_MODE_PARAM].value == 0), curr_params[TRIG_SRC_PARAM].value, curr_params[TRIG_EDGE_PARAM].value); fpga_update = 0; } if(state == rp_osc_idle_state) { usleep(10000); continue; } /* Time vector update? */ if(time_vect_update) { float unit_factor = rp_osc_get_time_unit_factor(curr_params[TIME_UNIT_PARAM].value); float t_acq = (curr_params[MAX_GUI_PARAM].value - curr_params[MIN_GUI_PARAM].value) / unit_factor; rp_osc_prepare_time_vector((float **)&rp_tmp_signals[0], dec_factor, curr_params[MIN_GUI_PARAM].value, curr_params[MAX_GUI_PARAM].value, curr_params[TIME_UNIT_PARAM].value); time_vect_update = 0; /* check if we have long acquisition - if yes the algorithm * (wait for pre-defined time and return partial signal) */ /* TODO: Make it programmable */ if(t_acq >= 1.5) { long_acq = 1; /* Catch initial trigger - we will poll trigger pointer, * when it changes we will act like official 'trigger' * came */ rp_osc_meas_clear(&ch1_meas); rp_osc_meas_clear(&ch2_meas); osc_fpga_get_wr_ptr(NULL, &long_acq_init_trig_ptr); } else { long_acq_first_wr_ptr = 0; long_acq_last_wr_ptr = 0; long_acq = 0; } long_acq_idx = 0; } /* Start new acquisition only if it is the index 0 (new acquisition) */ if(long_acq_idx == 0) { float time_delay = curr_params[TRIG_DLY_PARAM].value; /* Start the writting machine */ osc_fpga_arm_trigger(); /* Be sure to have enough time to load necessary history - wait */ if(time_delay < 0) { /* time delay is always in seconds - convert to [us] and * sleep */ usleep(round(-1 * time_delay * 1e6)); } else { if(curr_params[TIME_RANGE_PARAM].value > 4) usleep(5000); else usleep(1); } /* Start the trigger */ osc_fpga_set_trigger(trig_source); } /* start working */ pthread_mutex_lock(&rp_osc_ctrl_mutex); old_state = state = rp_osc_ctrl; pthread_mutex_unlock(&rp_osc_ctrl_mutex); if((state == rp_osc_idle_state) || (state == rp_osc_abort_state)) { continue; } else if(state == rp_osc_quit_state) { break; } if(long_acq_idx == 0) { /* polling until data is ready */ while(1) { pthread_mutex_lock(&rp_osc_ctrl_mutex); state = rp_osc_ctrl; params_dirty = rp_osc_params_dirty; pthread_mutex_unlock(&rp_osc_ctrl_mutex); /* change in state, abort polling */ if((state != old_state) || params_dirty) { break; } if(!long_acq && osc_fpga_triggered()) { /* for non-long acquisition wait for trigger */ break; } else if(long_acq) { int trig_ptr, curr_ptr; osc_fpga_get_wr_ptr(&curr_ptr, &trig_ptr); if((long_acq_init_trig_ptr != trig_ptr) || osc_fpga_triggered()) { /* FPGA wrote new trigger pointer - which means * new trigger happened */ break; } } usleep(1000); } } if((state != old_state) || params_dirty) { params_dirty = 0; continue; } if(long_acq) { /* Long acquisition - after trigger wait for a while to collect some * data */ /* TODO: Make it programmable - Sleep for 200 [ms] */ const int long_acq_part_delay = 1000 * 200; if(long_acq_idx == 0) { /* Trigger - so let's arrange all the needed pointers & stuff */ int wr_ptr_curr, wr_ptr_trig; float smpl_period = c_osc_fpga_smpl_period * dec_factor; int t_start_idx = round(curr_params[MIN_GUI_PARAM].value / smpl_period); float unit_factor = rp_osc_get_time_unit_factor( curr_params[TIME_UNIT_PARAM].value); float t_acq = (curr_params[MAX_GUI_PARAM].value - curr_params[MIN_GUI_PARAM].value) / unit_factor; osc_fpga_get_wr_ptr(&wr_ptr_curr, &wr_ptr_trig); long_acq_first_wr_ptr = wr_ptr_trig + t_start_idx - 3; if(long_acq_first_wr_ptr < 0) long_acq_first_wr_ptr = OSC_FPGA_SIG_LEN + long_acq_first_wr_ptr; long_acq_last_wr_ptr = long_acq_first_wr_ptr + (t_acq / (c_osc_fpga_smpl_period * dec_factor)); long_acq_last_wr_ptr = long_acq_last_wr_ptr % OSC_FPGA_SIG_LEN; if(round((t_acq / (c_osc_fpga_smpl_period * dec_factor) / (((int)rp_get_params_bode(5))-1))) < 0) long_acq_step = 1; else long_acq_step = round((t_acq / (c_osc_fpga_smpl_period * dec_factor)) / (((int)rp_get_params_bode(5))-1)); rp_osc_meas_clear(&ch1_meas); rp_osc_meas_clear(&ch2_meas); } /* we are after trigger - so let's wait a while to collect some * samples */ usleep(long_acq_part_delay); /* Sleep for 200 [ms] */ } pthread_mutex_lock(&rp_osc_ctrl_mutex); state = rp_osc_ctrl; params_dirty = rp_osc_params_dirty; pthread_mutex_unlock(&rp_osc_ctrl_mutex); if((state != old_state) || params_dirty) continue; if(!long_acq) { /* Triggered, decimate & convert the values */ rp_osc_meas_clear(&ch1_meas); rp_osc_meas_clear(&ch2_meas); bode_start_measure((float **)&rp_tmp_signals[1], &rp_fpga_cha_signal[0], (float **)&rp_tmp_signals[2], &rp_fpga_chb_signal[0], (float **)&rp_tmp_signals[0]); } else { long_acq_idx = rp_osc_decimate_partial((float **)&rp_tmp_signals[1], &rp_fpga_cha_signal[0], (float **)&rp_tmp_signals[2], &rp_fpga_chb_signal[0], (float **)&rp_tmp_signals[0], &long_acq_first_wr_ptr, long_acq_last_wr_ptr, long_acq_step, long_acq_idx, curr_params[MIN_GUI_PARAM].value, dec_factor, curr_params[TIME_UNIT_PARAM].value, &ch1_meas, &ch2_meas, ch1_max_adc_v, ch2_max_adc_v, curr_params[GEN_DC_OFFS_1].value, curr_params[GEN_DC_OFFS_2].value); /* Acquisition over, start one more! */ if(long_acq_idx >= ((int)rp_get_params_bode(5))-1) { long_acq_idx = 0; osc_fpga_get_wr_ptr(NULL, &long_acq_init_trig_ptr); if(state == rp_osc_single_state) { rp_osc_worker_change_state(rp_osc_idle_state); } } } /* check again for change of state */ pthread_mutex_lock(&rp_osc_ctrl_mutex); state = rp_osc_ctrl; pthread_mutex_unlock(&rp_osc_ctrl_mutex); /* We have acquisition - if we are in single put state machine * to idle */ if((state == rp_osc_single_state) && (!long_acq)) { rp_osc_worker_change_state(rp_osc_idle_state); } /* copy the results to the user buffer - if we are finished or not */ if(!long_acq || long_acq_idx == 0) { /* Finish the measurement */ rp_osc_meas_avg_amp(&ch1_meas, OSC_FPGA_SIG_LEN); rp_osc_meas_avg_amp(&ch2_meas, OSC_FPGA_SIG_LEN); rp_osc_meas_period(&ch1_meas, &ch2_meas, &rp_fpga_cha_signal[0], &rp_fpga_chb_signal[0], dec_factor); rp_osc_meas_convert(&ch1_meas, ch1_max_adc_v, rp_calib_params->fe_ch1_dc_offs); rp_osc_meas_convert(&ch2_meas, ch2_max_adc_v, rp_calib_params->fe_ch2_dc_offs); rp_osc_set_meas_data(ch1_meas, ch2_meas); rp_osc_set_signals(rp_tmp_signals, ((int)rp_get_params_bode(5))-1); } else { rp_osc_set_signals(rp_tmp_signals, long_acq_idx); } /* do not loop too fast */ usleep(10000); } rp_clean_params(curr_params); return 0; }