/* Find a suitable FPGA decimation factor and trigger delay, * based on xmin & xmax zoom conntrols */ int transform_acq_params(rp_app_params_t *p) { TRACE("%s()\n", __FUNCTION__); int ret = 0; int i; /* Skip the transform in case auto-set is in progress */ if ( (p[AUTO_FLAG_PARAM].value == 1) || (auto_in_progress == 1)) { return ret; } double xmin = p[MIN_GUI_PARAM].value; double xmax = p[MAX_GUI_PARAM].value; float ratio; int reset_zoom = 0; int time_unit = p[TIME_UNIT_PARAM].value; float t_unit_factor = pow(10, 3*(2 - time_unit)); /* When exactly this pair is provided by client, Reset Zoom is requested. */ if ((xmax == 1.0e6) && (xmin == -1.0e6)) { reset_zoom = 1; } /* Server ForceX state */ p[FORCEX_FLAG_PARAM].value = (float) forcex_state; /* Difference (expressed as ratio) between forced values and GUI state */ if ((xmax - xmin) != 0) { ratio = fabs(forced_xmax - forced_xmin) / fabs(xmax - xmin); } else { ratio = 0.0; } /* Make it always between 0 and 1 (0: very different, 1 equal) */ if (ratio > 1) { ratio = 1.0 / ratio; } /* Stop forcing if factor 33 of difference or less */ if (ratio > 0.03) { p[FORCEX_FLAG_PARAM].value = 0; forcex_state = 0; } /* Contver GUI values to seconds */ xmin /= t_unit_factor; xmax /= t_unit_factor; TRACE("TR: Xmin, Xmax: %10.8f, %10.8f\n", xmin, xmax); int time_unit_gui = time_unit; int dec; double rdec; /* Calculate the suitable FPGA decimation setting that optimally covers the GUI time frame */ if (p[TRIG_MODE_PARAM].value == 0) { /* Autotriggering mode => acquisition starts at time t = 0 */ rdec = (xmax - 0) * c_osc_fpga_smpl_freq / OSC_FPGA_SIG_LEN; } else { double rxmax = (xmax < 0) ? 0 : xmax; rdec = (rxmax - xmin) * c_osc_fpga_smpl_freq / OSC_FPGA_SIG_LEN; } /* Find optimal decimation setting */ for (i = 0; i < 6; i++) { dec = osc_fpga_cnv_time_range_to_dec(i); if (dec >= rdec) { break; } } if (i > 5) i = 5; /* Apply decimation parameter (time range), but not when forcing GUI client * or during reset zoom. */ if ((forcex_state == 0) && (reset_zoom == 0)) { p[TIME_RANGE_PARAM].value = i; } TRACE("TR: Dcimation: %6.2f -> %dx\n", rdec, dec); /* New time_unit & factor */ time_unit = time_range_to_time_unit(p[TIME_RANGE_PARAM].value); t_unit_factor = pow(10, 3*(2 - time_unit)); /* Update time unit Min and Max, but not if GUI hasn't responded to "forceX" command. */ if (forcex_state == 0) { p[MIN_GUI_PARAM].value = xmin * t_unit_factor; p[MAX_GUI_PARAM].value = xmax * t_unit_factor; p[GUI_XMIN].value = p[MIN_GUI_PARAM].value; p[GUI_XMAX].value = p[MAX_GUI_PARAM].value; p[TIME_UNIT_PARAM].value = time_unit; } else { p[MIN_GUI_PARAM].value = forced_xmin; p[MAX_GUI_PARAM].value = forced_xmax; p[GUI_XMIN].value = p[MIN_GUI_PARAM].value; p[GUI_XMAX].value = p[MAX_GUI_PARAM].value; p[TIME_UNIT_PARAM].value = forced_units; } /* If time units have changed by server: client MUST configure x axis * (ForceX is set for this purpose by server) to p[MIN_GUI_PARAM].value, * expressed in new units. */ TRACE("TR: New xmin, xmax [unit]: %6.2f %6.2f [%d]\n", p[MIN_GUI_PARAM].value, p[MAX_GUI_PARAM].value, (int)p[TIME_UNIT_PARAM].value); int64_t t_delay; /* Calculate necessary trigger delay expressed in FPGA decimated cycles */ if (p[TRIG_MODE_PARAM].value == 0) { /* Autotriggering mode => acquisition starts at time t = 0 */ t_delay= OSC_FPGA_SIG_LEN ; } else { t_delay= OSC_FPGA_SIG_LEN + (xmin * c_osc_fpga_smpl_freq / dec); } /* Trigger delay limitations/saturation */ const int64_t c_max_t_delay = ((int64_t)1 << 32) - 1; if (t_delay < 0) t_delay = 0; if (t_delay > c_max_t_delay) t_delay = c_max_t_delay; /* Trigger delay (reconverted in seconds) updated ONLY if client has responded to * last forceX command. */ if (forcex_state == 0) { p[TRIG_DLY_PARAM].value = ((t_delay - OSC_FPGA_SIG_LEN) * dec / c_osc_fpga_smpl_freq); } else { p[TRIG_DLY_PARAM].value = forced_delay; } /* Server issues a forceX command when time units change wrt. GUI (client) units */ if ((time_unit != time_unit_gui)) { p[FORCEX_FLAG_PARAM].value = 1.0; forcex_state = 1; /* Other settings frozen until GUI recovers */ forced_xmin = p[MIN_GUI_PARAM].value; forced_xmax = p[MAX_GUI_PARAM].value; forced_units = p[TIME_UNIT_PARAM].value; forced_delay = p[TRIG_DLY_PARAM].value; } /* When client issues a zoom reset, a particular ForceX command with * the initial 0 - 130 us time range. */ if (reset_zoom == 1) { p[FORCEX_FLAG_PARAM].value = 1.0; forcex_state = 1; forced_xmin = 0.0; forced_xmax = 130.0; forced_units = 0.0; forced_delay = 0; p[MIN_GUI_PARAM].value = forced_xmin; p[MAX_GUI_PARAM].value = forced_xmax; p[GUI_XMIN].value = p[MIN_GUI_PARAM].value; p[GUI_XMAX].value = p[MAX_GUI_PARAM].value; p[TIME_UNIT_PARAM].value = forced_units; p[TRIG_DLY_PARAM].value = forced_delay; p[TIME_RANGE_PARAM].value = 0; } TRACE("TR: Trigger delay: %.6f\n", p[TRIG_DLY_PARAM].value); return ret; }
/* Find a suitable FPGA decimation factor and trigger delay, * based on xmin & xmax zoom conntrols */ int transform_acq_params(rp_app_params_t *p) { int ret = 0; int i; double xmin = p[MIN_GUI_PARAM].value; double xmax = p[MAX_GUI_PARAM].value; float ratio; int reset_zoom=0; int time_unit = p[TIME_UNIT_PARAM].value; float t_unit_factor = pow(10, 3*(2 - time_unit)); // When exactly this pair provided by client Reset Zoom is requested if ((xmax==1.0e6) && (xmin==-1.0e6)) reset_zoom=1; TRACE("tu = %d, tf = %10.8f\n", time_unit, t_unit_factor); // Retrieve Server ForceX state p[FORCEX_FLAG_PARAM].value = (float) forcex_state; // Difference (expressed as ratio) between forced values and GUI state if ((xmax-xmin) !=0) ratio=fabs(forced_xmax-forced_xmin)/fabs(xmax-xmin); else ratio=0; if (ratio>1) // Make it always between 0 and 1 (0: very different, 1 equal) ratio=1/ratio; if (ratio > 0.03) // Stop forcing if factor 33 of difference or less { p[FORCEX_FLAG_PARAM].value = 0; forcex_state=0; } // Contver GUI values to seconds xmin /= t_unit_factor; xmax /= t_unit_factor; TRACE("Xmin, Xmax: %10.8f, %10.8f\n", xmin, xmax); int time_unit_gui=time_unit; int dec; double rdec; // Calculate the suitable FPGA decimation setting that optimally covers the GUI time frame if (p[TRIG_MODE_PARAM].value==0) // Autotriggering mode => acquisition starts at time t=0 rdec= (xmax - 0) * c_osc_fpga_smpl_freq / OSC_FPGA_SIG_LEN; else rdec= (xmax - xmin) * c_osc_fpga_smpl_freq / OSC_FPGA_SIG_LEN; for (i = 0; i < 6; i++) { dec = osc_fpga_cnv_time_range_to_dec(i); if (dec >= rdec) { break; } } if (i > 5) i = 5; // Optimal decimation setting identified // Apply decimation parameter (time range), but not when forcing GUI client or during reset zoom. if ((forcex_state==0) && (reset_zoom==0)) p[TIME_RANGE_PARAM].value = i; TRACE("Dcimation: %6.2f -> %dx\n", rdec, dec); TRACE("Time range: %d\n", i); TRACE("Reset zoom: %d\n", reset_zoom); /* New time_unit & factor */ time_unit = time_range_to_time_unit(p[TIME_RANGE_PARAM].value); t_unit_factor = pow(10, 3*(2 - time_unit)); if (forcex_state==0) // Update time unit Min and Max, but not if GUI hasn't responded to "forceX" command. { p[MIN_GUI_PARAM].value = xmin * t_unit_factor; p[MAX_GUI_PARAM].value = xmax * t_unit_factor; p[TIME_UNIT_PARAM].value = time_unit; } else { p[MIN_GUI_PARAM].value = forced_xmin; p[MAX_GUI_PARAM].value = forced_xmax; p[TIME_UNIT_PARAM].value = forced_units; } // If time units changed by server: client MUST configure x axis (ForceX is set for this purpose by server) // to p[MIN_GUI_PARAM].value, p[MIN_GUI_PARAM].value expressed in new units TRACE("New xmin, xmax [unit]: %6.2f %6.2f [%d]\n", p[MIN_GUI_PARAM].value, p[MAX_GUI_PARAM].value, (int)p[TIME_UNIT_PARAM].value); int64_t t_delay; // Calculating necessary trigger delay expressed in FPGA decimated cycles if (p[TRIG_MODE_PARAM].value==0) // Autotriggering mode => acquisition starts at time t=0 t_delay= OSC_FPGA_SIG_LEN ; else t_delay= OSC_FPGA_SIG_LEN + (xmin * c_osc_fpga_smpl_freq / dec); // Some limitations... if (t_delay < 0) t_delay = 0; if (t_delay > ((int64_t)1 << 32) - 1) t_delay = ((int64_t)1 << 32) - 1; TRACE("Trigger delay: %d\n", (int)t_delay); if (forcex_state==0) // Trigger delay (reconverted in seconds) updated ONLY if client has responded to last forceX command p[TRIG_DLY_PARAM].value = ((t_delay - OSC_FPGA_SIG_LEN) * dec / c_osc_fpga_smpl_freq); else p[TRIG_DLY_PARAM].value =forced_delay; // Server issues a forceX command when time units change wrt. GUI (client) units if ((time_unit != time_unit_gui)) { p[FORCEX_FLAG_PARAM].value = 1.0; forcex_state=1; forced_xmin=p[MIN_GUI_PARAM].value; // Other settings frozen until GUI recovers forced_xmax=p[MAX_GUI_PARAM].value; forced_units=p[TIME_UNIT_PARAM].value; forced_delay=p[TRIG_DLY_PARAM].value; } if (reset_zoom==1) // When client issues a zoom reset, a particular ForceX command with the initial 0 - 130 us time range { p[FORCEX_FLAG_PARAM].value = 1.0; forced_xmin=0.0; forced_xmax=130.0; forced_units=0.0; forced_delay=0; forcex_state=1; p[MIN_GUI_PARAM].value = forced_xmin; p[MAX_GUI_PARAM].value = forced_xmax; p[TIME_UNIT_PARAM].value = forced_units; p[TRIG_DLY_PARAM].value=forced_delay; p[TIME_RANGE_PARAM].value = 0; } TRACE("Trigger delay: %10.6f\n", p[TRIG_DLY_PARAM].value); return ret; }