int rp_set_params(rp_app_params_t *p, int len) { int i; int fpga_update = 1; int params_change = 0; int awg_params_change = 0; TRACE("%s()\n", __FUNCTION__); if(len > PARAMS_NUM) { fprintf(stderr, "Too many parameters, max=%d\n", PARAMS_NUM); return -1; } pthread_mutex_lock(&rp_main_params_mutex); for(i = 0; i < len || p[i].name != NULL; i++) { int p_idx = -1; int j = 0; /* Search for correct parameter name in defined parameters */ while(rp_main_params[j].name != NULL) { int p_strlen = strlen(p[i].name); if(p_strlen != strlen(rp_main_params[j].name)) { j++; continue; } if(!strncmp(p[i].name, rp_main_params[j].name, p_strlen)) { p_idx = j; break; } j++; } if(p_idx == -1) { fprintf(stderr, "Parameter %s not found, ignoring it\n", p[i].name); continue; } if(rp_main_params[p_idx].read_only) continue; if(rp_main_params[p_idx].value != p[i].value) { if(p_idx < PARAMS_AWG_PARAMS) params_change = 1; if(p_idx >= PARAMS_AWG_PARAMS) awg_params_change = 1; if(rp_main_params[p_idx].fpga_update) fpga_update = 1; } if(rp_main_params[p_idx].min_val > p[i].value) { fprintf(stderr, "Incorrect parameters value: %f (min:%f), " " correcting it\n", p[i].value, rp_main_params[p_idx].min_val); p[i].value = rp_main_params[p_idx].min_val; } else if(rp_main_params[p_idx].max_val < p[i].value) { fprintf(stderr, "Incorrect parameters value: %f (max:%f), " " correcting it\n", p[i].value, rp_main_params[p_idx].max_val); p[i].value = rp_main_params[p_idx].max_val; } rp_main_params[p_idx].value = p[i].value; } transform_from_iface_units(&rp_main_params[0]); pthread_mutex_unlock(&rp_main_params_mutex); /* Set parameters in HW/FPGA only if they have changed */ if(params_change || (params_init == 0)) { pthread_mutex_lock(&rp_main_params_mutex); /* Xmin & Xmax public copy to be served to clients */ rp_main_params[GUI_XMIN].value = p[MIN_GUI_PARAM].value; rp_main_params[GUI_XMAX].value = p[MAX_GUI_PARAM].value; transform_acq_params(rp_main_params); pthread_mutex_unlock(&rp_main_params_mutex); /* First do health check and then send it to the worker! */ int mode = rp_main_params[TRIG_MODE_PARAM].value; int time_range = rp_main_params[TIME_RANGE_PARAM].value; int time_unit = 2; /* Get info from FPGA module about clocks/decimation, ...*/ int dec_factor = osc_fpga_cnv_time_range_to_dec(time_range); float smpl_period = c_osc_fpga_smpl_period * dec_factor; /* t_delay - trigger delay in seconds */ float t_delay = rp_main_params[TRIG_DLY_PARAM].value; float t_unit_factor = 1; /* to convert to seconds */ /* Our time window with current settings: * - time_delay is added later, when we check if it is correct * setting */ float t_min = 0; float t_max = ((OSC_FPGA_SIG_LEN-1) * smpl_period); float t_max_minus = ((OSC_FPGA_SIG_LEN-6) * smpl_period); params_init = 1; /* in time units time_unit, needs to be converted */ float t_start = rp_main_params[MIN_GUI_PARAM].value; float t_stop = rp_main_params[MAX_GUI_PARAM].value; int t_start_idx; int t_stop_idx; int t_step_idx = 0; /* If auto-set algorithm was requested do not set other parameters */ if(rp_main_params[AUTO_FLAG_PARAM].value == 1) { auto_in_progress = 1; forcex_state = 0; rp_osc_clean_signals(); rp_osc_worker_change_state(rp_osc_auto_set_state); /* AUTO_FLAG_PARAM is cleared when Auto-set algorithm finishes */ /* Wait for auto-set algorithm to finish or timeout */ int timeout = 10000000; // [us] const int step = 50000; // [us] rp_osc_worker_state_t state; while (timeout > 0) { rp_osc_worker_get_state(&state); if (state != rp_osc_auto_set_state) { break; } usleep(step); timeout -= step; } if (timeout <= 0) { fprintf(stderr, "AUTO: Timeout waiting for AUTO-set algorithm to finish.\n"); } auto_in_progress = 0; return 0; } /* If AUTO trigger mode, reset trigger delay */ if(mode == 0) t_delay = 0; if(dec_factor < 0) { fprintf(stderr, "Incorrect time range: %d\n", time_range); return -1; } /* Pick time unit and unit factor corresponding to current time range. */ if((time_range == 0) || (time_range == 1)) { time_unit = 0; t_unit_factor = 1e6; } else if((time_range == 2) || (time_range == 3)) { time_unit = 1; t_unit_factor = 1e3; } rp_main_params[TIME_UNIT_PARAM].value = time_unit; TRACE("PC: time_(R,U) = (%d, %d)\n", time_range, time_unit); /* Check if trigger delay in correct range, otherwise correct it * Correct trigger delay is: * t_delay >= -t_max_minus * t_delay <= OSC_FPGA_MAX_TRIG_DELAY */ if(t_delay < -t_max_minus) { t_delay = -t_max_minus; } else if(t_delay > (OSC_FPGA_TRIG_DLY_MASK * smpl_period)) { t_delay = OSC_FPGA_TRIG_DLY_MASK * smpl_period; } else { t_delay = round(t_delay / smpl_period) * smpl_period; } t_min = t_min + t_delay; t_max = t_max + t_delay; rp_main_params[TRIG_DLY_PARAM].value = t_delay; /* Convert to seconds */ t_start = t_start / t_unit_factor; t_stop = t_stop / t_unit_factor; TRACE("PC: t_stop = %.9f\n", t_stop); /* Select correct time window with this settings: * time window is defined from: * ([ 0 - 16k ] * smpl_period) + trig_delay */ /* round to correct/possible values - convert to nearest index * and back */ t_start_idx = round(t_start / smpl_period); t_stop_idx = round(t_stop / smpl_period); t_start = (t_start_idx * smpl_period); t_stop = (t_stop_idx * smpl_period); if(t_start < t_min) t_start = t_min; if(t_stop > t_max) t_stop = t_max; if(t_stop <= t_start ) t_stop = t_max; /* Correct the window according to possible decimations - always * provide at least the data demanded by the user (ceil() instead * of round()) */ 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_idx = ceil((t_stop_idx-t_start_idx)/(float)(SIGNAL_LENGTH-1)); int max_step = OSC_FPGA_SIG_LEN/SIGNAL_LENGTH; if(t_step_idx > max_step) t_step_idx = max_step; t_stop = t_start + SIGNAL_LENGTH * t_step_idx * smpl_period; } TRACE("PC: t_stop (rounded) = %.9f\n", t_stop); /* write back and convert to set units */ rp_main_params[MIN_GUI_PARAM].value = t_start; rp_main_params[MAX_GUI_PARAM].value = t_stop; rp_osc_worker_update_params((rp_app_params_t *)&rp_main_params[0], fpga_update); /* check if we need to change state */ switch(mode) { case 0: /* auto */ rp_osc_worker_change_state(rp_osc_auto_state); break; case 1: /* normal */ rp_osc_worker_change_state(rp_osc_normal_state); break; case 2: /* single - clear last ok buffer */ rp_osc_worker_change_state(rp_osc_idle_state); rp_osc_clean_signals(); break; default: return -1; } if(rp_main_params[SINGLE_BUT_PARAM].value == 1) { rp_main_params[SINGLE_BUT_PARAM].value = 0; rp_osc_clean_signals(); rp_osc_worker_change_state(rp_osc_single_state); } } if(awg_params_change) { /* Correct frequencies if needed */ rp_main_params[GEN_SIG_FREQ_CH1].value = rp_gen_limit_freq(rp_main_params[GEN_SIG_FREQ_CH1].value, rp_main_params[GEN_SIG_TYPE_CH1].value); rp_main_params[GEN_SIG_FREQ_CH2].value = rp_gen_limit_freq(rp_main_params[GEN_SIG_FREQ_CH2].value, rp_main_params[GEN_SIG_TYPE_CH2].value); if(generate_update(&rp_main_params[0]) < 0) { return -1; } } return 0; }
int rp_set_params(rp_app_params_t *p, int len) { int i; int fpga_update = 1; int params_change = 0; int awg_params_change = 0; if(len > PARAMS_NUM) { fprintf(stderr, "Too much parameters, max=%d\n", PARAMS_NUM); return -1; } pthread_mutex_lock(&rp_main_params_mutex); for(i = 0; i < len || p[i].name != NULL; i++) { int p_idx = -1; int j = 0; /* Search for correct parameter name in defined parameters */ while(rp_main_params[j].name != NULL) { int p_strlen = strlen(p[i].name); if(p_strlen != strlen(rp_main_params[j].name)) { j++; continue; } if(!strncmp(p[i].name, rp_main_params[j].name, p_strlen)) { p_idx = j; break; } j++; } if(p_idx == -1) { fprintf(stderr, "Parameter %s not found, ignoring it\n", p[i].name); continue; } if(rp_main_params[p_idx].read_only) continue; if(rp_main_params[p_idx].value != p[i].value) { if(p_idx < PARAMS_AWG_PARAMS) params_change = 1; if(p_idx >= PARAMS_AWG_PARAMS) awg_params_change = 1; if(rp_main_params[p_idx].fpga_update) fpga_update = 1; } if(rp_main_params[p_idx].min_val > p[i].value) { fprintf(stderr, "Incorrect parameters value: %f (min:%f), " " correcting it\n", p[i].value, rp_main_params[p_idx].min_val); p[i].value = rp_main_params[p_idx].min_val; } else if(rp_main_params[p_idx].max_val < p[i].value) { fprintf(stderr, "Incorrect parameters value: %f (max:%f), " " correcting it\n", p[i].value, rp_main_params[p_idx].max_val); p[i].value = rp_main_params[p_idx].max_val; } rp_main_params[p_idx].value = p[i].value; } pthread_mutex_unlock(&rp_main_params_mutex); if(params_change || (params_init == 0)) { pthread_mutex_lock(&rp_main_params_mutex); transform_acq_params(rp_main_params); pthread_mutex_unlock(&rp_main_params_mutex); /* First do health check and then send it to the worker! */ int mode = rp_main_params[TRIG_MODE_PARAM].value; int time_range = rp_main_params[TIME_RANGE_PARAM].value; int time_unit = 2; /* Get info from FPGA module about clocks/decimation, ...*/ int dec_factor = osc_fpga_cnv_time_range_to_dec(time_range); float smpl_period = c_osc_fpga_smpl_period * dec_factor; /* t_delay - trigger delay in seconds */ float t_delay = rp_main_params[TRIG_DLY_PARAM].value; float t_unit_factor = 1; /* to convert to seconds */ TRACE("After T: %d, %dx\n", time_range, dec_factor); /* Our time window with current settings: * - time_delay is added later, when we check if it is correct * setting */ float t_min = 0; float t_max = ((OSC_FPGA_SIG_LEN-1) * smpl_period); params_init = 1; /* in time units time_unit, needs to be converted */ float t_start = rp_main_params[MIN_GUI_PARAM].value; float t_stop = rp_main_params[MAX_GUI_PARAM].value; int t_start_idx; int t_stop_idx; int t_step_idx = 0; float ch1_max_adc_v, ch2_max_adc_v; float ch1_delta, ch2_delta; /* If auto-set algorithm was requested do not set other parameters */ if(rp_main_params[AUTO_FLAG_PARAM].value == 1) { rp_osc_clean_signals(); rp_osc_worker_change_state(rp_osc_auto_set_state); /* AUTO_FLAG_PARAM is cleared when Auto-set algorithm finishes */ /* rp_main_params[AUTO_FLAG_PARAM].value = 0;*/ /* Wait for auto-set algorithm to finish or timeout */ int timeout = 10000000; // [us] const int step = 50000; // [us] rp_osc_worker_state_t state; while (timeout > 0) { rp_osc_worker_get_state(&state); if (state != rp_osc_auto_set_state) { break; } usleep(step); timeout -= step; } if (timeout <= 0) { fprintf(stderr, "AUTO: Timeout waiting for AUTO-set algorithm to finish.\n"); } return 0; } /* if AUTO reset trigger delay */ if(mode == 0) t_delay = 0; if(dec_factor < 0) { fprintf(stderr, "Incorrect time range: %d\n", time_range); return -1; } /* pick correct which time unit is selected */ if((time_range == 0) || (time_range == 1)) { time_unit = 0; t_unit_factor = 1e6; } else if((time_range == 2) || (time_range == 3)) { time_unit = 1; t_unit_factor = 1e3; } TRACE("After T: time_unit = %d\n", time_unit); rp_main_params[TIME_UNIT_PARAM].value = time_unit; /* Check if trigger delay in correct range, otherwise correct it * Correct trigger delay is: * t_delay >= -t_max * t_delay <= OSC_FPGA_MAX_TRIG_DELAY */ if(t_delay < -t_max) { t_delay = -t_max; } else if(t_delay > (OSC_FPGA_TRIG_DLY_MASK * smpl_period)) { t_delay = OSC_FPGA_TRIG_DLY_MASK * smpl_period; } else { t_delay = round(t_delay / smpl_period) * smpl_period; } t_min = t_min + t_delay; t_max = t_max + t_delay; rp_main_params[TRIG_DLY_PARAM].value = t_delay; /* convert to seconds */ t_start = t_start / t_unit_factor; t_stop = t_stop / t_unit_factor; /* Select correct time window with this settings: * time window is defined from: * ([ 0 - 16k ] * smpl_period) + trig_delay */ /* round to correct/possible values - convert to nearest index * and back */ t_start_idx = round(t_start / smpl_period); t_stop_idx = round(t_stop / smpl_period); t_start = (t_start_idx * smpl_period); t_stop = (t_stop_idx * smpl_period); if(t_start < t_min) t_start = t_min; if(t_stop > t_max) t_stop = t_max; if(t_stop <= t_start ) t_stop = t_max; /* Correct the window according to possible decimations - always * provide at least the data demanded by the user (ceil() instead * of round()) */ t_start_idx = round(t_start / smpl_period); t_stop_idx = round(t_stop / smpl_period); if((((t_stop_idx-t_start_idx)/(float)((rp_main_params[LCR_STEPS].value)-1))) < 1) t_step_idx = 1; else { t_step_idx = ceil((t_stop_idx-t_start_idx)/(float)((rp_main_params[LCR_STEPS].value)-1)); int max_step = OSC_FPGA_SIG_LEN/(rp_main_params[LCR_STEPS].value); if(t_step_idx > max_step) t_step_idx = max_step; } t_stop = t_start + (rp_main_params[LCR_STEPS].value) * t_step_idx * smpl_period; /* write back and convert to set units */ rp_main_params[MIN_GUI_PARAM].value = t_start; rp_main_params[MAX_GUI_PARAM].value = t_stop; /* Calculate new gui_reset_y_range */ if(rp_main_params[GAIN_CH1].value == 0) { ch1_max_adc_v = osc_fpga_calc_adc_max_v(rp_main_calib_params.fe_ch1_fs_g_hi, rp_main_params[PRB_ATT_CH1].value); } else { ch1_max_adc_v = osc_fpga_calc_adc_max_v(rp_main_calib_params.fe_ch1_fs_g_lo, rp_main_params[PRB_ATT_CH1].value); } if(rp_main_params[GAIN_CH2].value == 0) { ch2_max_adc_v = osc_fpga_calc_adc_max_v(rp_main_calib_params.fe_ch2_fs_g_hi, rp_main_params[PRB_ATT_CH2].value); } else { ch2_max_adc_v = osc_fpga_calc_adc_max_v(rp_main_calib_params.fe_ch2_fs_g_lo, rp_main_params[PRB_ATT_CH2].value); } if(ch1_max_adc_v > ch2_max_adc_v) rp_main_params[GUI_RST_Y_RANGE].value = 2.0 * ch1_max_adc_v; else rp_main_params[GUI_RST_Y_RANGE].value = 2.0 * ch2_max_adc_v; /* Re-calculate output parameters */ ch1_delta = (ch1_max_adc_v / rp_main_ch1_max_adc_v); ch2_delta = (ch2_max_adc_v / rp_main_ch2_max_adc_v); rp_main_ch1_max_adc_v = ch1_max_adc_v; rp_main_ch2_max_adc_v = ch2_max_adc_v; if(ch1_delta > ch2_delta) { rp_main_params[MIN_Y_PARAM].value *= ch1_delta; rp_main_params[MAX_Y_PARAM].value *= ch1_delta; } else { rp_main_params[MIN_Y_PARAM].value *= ch2_delta; rp_main_params[MAX_Y_PARAM].value *= ch2_delta; } rp_main_params[GEN_DC_OFFS_1].value *= ch1_delta; rp_main_params[GEN_DC_OFFS_2].value *= ch2_delta; if((int)rp_main_params[TRIG_SRC_PARAM].value == 0) { /* Trigger selected on Channel 1 */ rp_main_params[TRIG_LEVEL_PARAM].value *= ch1_delta; } else { /* Trigger selected on Channel 2 */ rp_main_params[TRIG_LEVEL_PARAM].value *= ch2_delta; } rp_osc_worker_update_params((rp_app_params_t *)&rp_main_params[0], fpga_update); /* check if we need to change state */ switch(mode) { case 0: /* auto */ rp_osc_worker_change_state(rp_osc_auto_state); break; case 1: /* normal */ rp_osc_worker_change_state(rp_osc_normal_state); break; case 2: /* single - clear last ok buffer */ rp_osc_worker_change_state(rp_osc_idle_state); rp_osc_clean_signals(); break; default: return -1; } if(rp_main_params[SINGLE_BUT_PARAM].value == 1) { rp_main_params[SINGLE_BUT_PARAM].value = 0; rp_osc_clean_signals(); rp_osc_worker_change_state(rp_osc_single_state); } } if(awg_params_change) { /* Correct frequencies if needed */ rp_main_params[GEN_SIG_FREQ_CH1].value = rp_gen_limit_freq(rp_main_params[GEN_SIG_FREQ_CH1].value, rp_main_params[GEN_SIG_TYPE_CH1].value); rp_main_params[GEN_SIG_FREQ_CH2].value = rp_gen_limit_freq(rp_main_params[GEN_SIG_FREQ_CH2].value, rp_main_params[GEN_SIG_TYPE_CH2].value); if(generate_update(&rp_main_params[0]) < 0) return -1; } return 0; }