From 8ca8f7fbf06ac9ce5f2817e31d6bae330f243aa1 Mon Sep 17 00:00:00 2001 From: "Michael J. Chudobiak" Date: Thu, 23 Aug 2012 14:49:16 -0400 Subject: added full error checker --- CMakeLists.txt | 2 +- device-functions.c | 20 +- device-functions.h | 4 + dummy_functions.c | 1 - dummy_functions.h | 1 - error_utils.c | 902 +++++++++++++++++++++++++++++++++++++++++++++++++++++ error_utils.h | 80 +---- globals.h | 85 ++++- string_utils.h | 2 - 9 files changed, 1007 insertions(+), 90 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c02b3ef..d14929f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ add_executable(instr-daemon instr-daemon.c ) add_executable(instr-client instr-client.c) -target_link_libraries(instr-daemon gio-2.0 gobject-2.0 glib-2.0 mhash) +target_link_libraries(instr-daemon gio-2.0 gobject-2.0 glib-2.0 mhash m) target_link_libraries(instr-client gio-2.0 gobject-2.0 glib-2.0) INSTALL(TARGETS instr-daemon instr-client diff --git a/device-functions.c b/device-functions.c index 081d63c..1ad00ba 100644 --- a/device-functions.c +++ b/device-functions.c @@ -1,6 +1,8 @@ #include "device-functions.h" #include "globals.h" #include "version.h" +#include "error_utils.h" +#include /*** BeginHeader idn_string */ @@ -24,17 +26,23 @@ int Set_frequency(int check_possible_only,int word_override,int range_override,i // all this does right now is check the frequency range, // and store the set value. + int check_valid; + /* abandon if high channel selected by user but not enabled by firmware */ if (channel && !globals.Flash.ChanKey_frequency) { return InvalidChannel; } - if (set_freq < globals.Flash.min_freq[channel]) { - return freq_lower_limit; - } - if (set_freq > globals.Flash.max_freq[channel]) { - return freq_upper_limit; - } + if (!check_possible_only) { + int i; + for (i=0; i + +ChannelStruct TestState[max_channels]; void idn_string(gchar** response); int Set_frequency(int check_possible_only,int word_override,int range_override,int channel,float set_freq); diff --git a/dummy_functions.c b/dummy_functions.c index 0bec20f..b370578 100644 --- a/dummy_functions.c +++ b/dummy_functions.c @@ -22,7 +22,6 @@ void GPIB_clear_events () {} void GPIB_change_address(int new_address) {} void Main_update_shift_registers() { } -void Error_check(void* p) { } int Set_Sav(int setting_num) {} int Set_Rcl(int setting_num) {} diff --git a/dummy_functions.h b/dummy_functions.h index 1f98cfa..78aa8d5 100644 --- a/dummy_functions.h +++ b/dummy_functions.h @@ -24,7 +24,6 @@ void GPIB_clear_events (); void GPIB_change_address(int new_address); void Main_update_shift_registers(); -void Error_check(void*); int Set_Sav(int setting_num); int Set_Rcl(int setting_num); diff --git a/error_utils.c b/error_utils.c index 50a0af8..6f9d85c 100644 --- a/error_utils.c +++ b/error_utils.c @@ -13,9 +13,11 @@ END DESCRIPTION **********************************************************/ #include #include +#include #include "globals.h" #include "dummy_functions.h" #include "lcd.h" +#include "error_utils.h" /*** EndHeader */ @@ -507,3 +509,903 @@ void get_error_text(gchar **response, int error_num) } + +int Error_check(ChannelStruct ChannelStateToTest[max_channels]) +{ + + float max_duty_high_ampl,max_duty_low_ampl,max_duty_this_ampl; + float ampl_fixed_max_duty; + float temp; + float duty_scale; + float duty_cycle; + int report_error; + + int i; + int num_of_chan; + + /* todo: check avrq settings */ + + num_of_chan=globals.Flash.channels; + if (num_of_chan==0) { + num_of_chan=1; + } + + + if (num_of_chan>1) { + if (!globals.Flash.ChanKey_frequency) for (i=1; i0.0) { + return pw_lower_limit; + } + + /* calculate maximum duty cycle based on amplitude and load, for later use */ + + max_duty_high_ampl=globals.Flash.max_duty_high[i]; + max_duty_low_ampl=globals.Flash.max_duty_low[i]; + + /* Choose highest of 4 duty cycles that meet max ampl limits */ + if (globals.Flash.duty_ampl[i]>0.0 && (fabs(ChannelStateToTest[i].amplitude)<= globals.Flash.duty_ampl[i])) { + max_duty_this_ampl=max_duty_low_ampl; + } else { + max_duty_this_ampl=max_duty_high_ampl; + } + + if (globals.Flash.duty_ampl_mid1[i]>0.0 && + (fabs(ChannelStateToTest[i].amplitude)<= globals.Flash.duty_ampl_mid1[i]) && + (globals.Flash.max_duty_mid1[i] > max_duty_this_ampl)) { + max_duty_this_ampl = globals.Flash.max_duty_mid1[i]; + } + + if (globals.Flash.duty_ampl_mid2[i]>0.0 && + (fabs(ChannelStateToTest[i].amplitude)<= globals.Flash.duty_ampl_mid2[i]) && + (globals.Flash.max_duty_mid2[i] > max_duty_this_ampl)) { + max_duty_this_ampl = globals.Flash.max_duty_mid2[i]; + } + + ampl_fixed_max_duty = max_duty_this_ampl; + if (globals.Flash.switchable_load[i]) { + ampl_fixed_max_duty = max_duty_this_ampl * (ChannelStateToTest[i].load_type / globals.Flash.low_load_type[i]); + temp = globals.Flash.max_high_rl_duty[i]; + if (ampl_fixed_max_duty > temp) { + ampl_fixed_max_duty = temp; + } + } + + + /* take burst mode and double-pulse mode into account when setting the maximum duty cycle */ + duty_scale = 100.0; /* convert from percent */ + + if (ChannelStateToTest[i].double_pulse==double_on) { + duty_scale = 200.0; + } + if ( (ChannelStateToTest[i].burst_count>1) + && (globals.Flash.max_burst_count[i]>1) + && !globals.Flash.burst_func[i]) { + duty_scale *= (float) ChannelStateToTest[i].burst_count; + } + + + if (ChannelStateToTest[i].trigger_source==source_internal) { + + /* --- check minimum frequency --- */ + globals.Constraints.err_min_freq[i]=globals.Flash.min_freq[i]; + + if (ChannelStateToTest[i].frequency<(0.999*globals.Constraints.err_min_freq[i])) { + report_error=freq_lower_limit; + } + + if ((ChannelStateToTest[i].polarity!=pol_norm) && (globals.Flash.min_pw[i]>0.0)) { + temp=(1/ChannelStateToTest[i].pw)*( 1.0- ampl_fixed_max_duty/duty_scale ); + if (temp>globals.Constraints.err_min_freq[i]) { + globals.Constraints.err_min_freq[i]=temp; + if (ChannelStateToTest[i].frequency<(0.999*globals.Constraints.err_min_freq[i])) { + report_error=duty_cycle_upper_limit; + } + } + } + + + /* ------------------------------- */ + + /* --- check maximum frequency --- */ + globals.Constraints.err_max_freq[i]=globals.Flash.max_freq[i]; + + if (ChannelStateToTest[i].frequency>(1.001*globals.Constraints.err_max_freq[i])) { + report_error=freq_upper_limit; + } + + if (fabs(ChannelStateToTest[i].delay)>1.0e-15) { + temp=0.95/fabs(ChannelStateToTest[i].delay); + if (temp(1.001*globals.Constraints.err_max_freq[i])) { + report_error=Delay_Exceeds_95Period; + } + } + } + + if (globals.Flash.min_pw[i] > 0.0) { + temp=1/ChannelStateToTest[i].pw; + if (temp(1.001*globals.Constraints.err_max_freq[i])) { + report_error=PW_Exceeds_Period; + } + } + + if ( (ChannelStateToTest[i].burst_count>1) + && (globals.Flash.max_burst_count[i]>1) + && !globals.Flash.burst_func[i]) { + temp=1/(ChannelStateToTest[i].burst_count * (ChannelStateToTest[i].pw+ChannelStateToTest[i].burst_time)); + if (temp(1.001*globals.Constraints.err_max_freq[i])) { + report_error=Burst_Exceeds_Period; + } + } + } + + if (ChannelStateToTest[i].polarity==pol_norm) { + temp=(1/ChannelStateToTest[i].pw)*(ampl_fixed_max_duty/duty_scale); + if (temp(1.001*globals.Constraints.err_max_freq[i])) { + report_error=duty_cycle_upper_limit; + } + } + } + + if (ChannelStateToTest[i].double_pulse==double_on) { + temp=0.95/(ChannelStateToTest[i].pw+fabs(ChannelStateToTest[i].delay)); + if (temp(1.001*globals.Constraints.err_max_freq[i])) { + report_error=Double_Separation_Too_Large; + } + } + } + + if ((globals.Flash.max_avg_ampl[i]) > 0.0 && (fabs(ChannelStateToTest[i].amplitude)) > 0.0) { + temp=100.0 * globals.Flash.max_avg_ampl[i] / + (fabs(ChannelStateToTest[i].amplitude) * ChannelStateToTest[i].pw * duty_scale); + if (temp(1.001*globals.Constraints.err_max_freq[i])) { + report_error=Average_Amplitude_Too_High; + } + } + } + + if (globals.Flash.max_avg_power[i] > 0.0) { + temp = (globals.Flash.max_avg_power[i] * ChannelStateToTest[i].load_type) / (ChannelStateToTest[i].amplitude * ChannelStateToTest[i].amplitude * ChannelStateToTest[i].pw); + if (temp < globals.Constraints.err_max_freq[i]) { + globals.Constraints.err_max_freq[i] = temp; + if (ChannelStateToTest[i].frequency>(1.001*globals.Constraints.err_max_freq[i])) { + report_error=average_power_limit; + } + } + } + + } + + /* ------------------------------- */ + } + + /* --- check minimum pulse width --- */ + globals.Constraints.err_min_pw[i]=globals.Flash.min_pw[i]; + + if ( (globals.Constraints.err_min_pw[i]>=0.0 && ChannelStateToTest[i].pw<(0.999*globals.Constraints.err_min_pw[i])) + || (globals.Constraints.err_min_pw[i]<0.0 && ChannelStateToTest[i].pw<(1.001*globals.Constraints.err_min_pw[i])) ) { + report_error=pw_lower_limit; + } + + /* negative-pw units are special, ignore PRF / duty cycle / PW conflicts */ + if (globals.Constraints.err_min_pw[i]>=0.0) { + if (ChannelStateToTest[i].trigger_source==source_internal) { + if (ChannelStateToTest[i].polarity!=pol_norm) { + temp=(1/ChannelStateToTest[i].frequency)*( 1.0 - ampl_fixed_max_duty/duty_scale ); + if (temp>globals.Constraints.err_min_pw[i]) { + globals.Constraints.err_min_pw[i]=temp; + if (ChannelStateToTest[i].pw<(0.999*globals.Constraints.err_min_pw[i])) { + report_error=duty_cycle_upper_limit; + } + } + } + } + } + + /* ------------------------------- */ + + + /* --- check maximum pw ---------- */ + globals.Constraints.err_max_pw[i]=globals.Flash.max_pw[i]; + + /* polarity overrides */ + if ((ChannelStateToTest[i].amplitude >= 0.0) && (globals.Flash.max_pw_pol[i][0] > 0.0) && (globals.Constraints.err_max_pw[i] > globals.Flash.max_pw_pol[i][0])) { + globals.Constraints.err_max_pw[i] = globals.Flash.max_pw_pol[i][0]; + } else if ((ChannelStateToTest[i].amplitude <0.0) && (globals.Flash.max_pw_pol[i][1] > 0.0) && (globals.Constraints.err_max_pw[i] > globals.Flash.max_pw_pol[i][1])) { + globals.Constraints.err_max_pw[i] = globals.Flash.max_pw_pol[i][1]; + } + + if (ChannelStateToTest[i].pw>(1.001*globals.Constraints.err_max_pw[i])) { + report_error=pw_upper_limit; + } + + if (ChannelStateToTest[i].double_pulse==double_on) { + temp=ChannelStateToTest[i].delay; + if (temp(1.001*globals.Constraints.err_max_pw[i])) { + report_error=PW_Exceeds_Double_Separation; + } + } + } + + if (ChannelStateToTest[i].trigger_source==source_internal) { + temp=1/ChannelStateToTest[i].frequency; + if (temp(1.001*globals.Constraints.err_max_pw[i])) { + report_error=PW_Exceeds_Period; + } + } + + if ( (ChannelStateToTest[i].burst_count>1) + && (globals.Flash.max_burst_count[i]>1) + && !globals.Flash.burst_func[i]) { + temp=(1/ChannelStateToTest[i].frequency)/ChannelStateToTest[i].burst_count - ChannelStateToTest[i].burst_time; + if (temp(1.001*globals.Constraints.err_max_pw[i])) { + report_error=Burst_Exceeds_Period; + } + } + } + + if (ChannelStateToTest[i].polarity==pol_norm) { + temp=(1/ChannelStateToTest[i].frequency)*(ampl_fixed_max_duty/duty_scale); + if (temp(1.001*globals.Constraints.err_max_pw[i])) { + report_error=duty_cycle_upper_limit; + } + } + } + + if (ChannelStateToTest[i].double_pulse==double_on) { + temp=(0.95/ChannelStateToTest[i].frequency)-ChannelStateToTest[i].delay; + if (temp(1.001*globals.Constraints.err_max_pw[i])) { + report_error=Double_Separation_Too_Large; + } + } + } + + if ((globals.Flash.max_avg_ampl[i]) > 0.0 && (fabs(ChannelStateToTest[i].amplitude)) > 0.0) { + temp=100.0 * globals.Flash.max_avg_ampl[i] / + (fabs(ChannelStateToTest[i].amplitude) * ChannelStateToTest[i].frequency * duty_scale); + if (temp(1.001*globals.Constraints.err_max_pw[i])) { + report_error=Average_Amplitude_Too_High; + } + } + } + + if (globals.Flash.max_avg_power[i] > 0.0) { + temp = globals.Flash.max_avg_power[i] * ChannelStateToTest[i].load_type / (ChannelStateToTest[i].amplitude * ChannelStateToTest[i].amplitude * ChannelStateToTest[i].frequency); + if (temp < globals.Constraints.err_max_pw[i]) { + globals.Constraints.err_max_pw[i] = temp; + if (ChannelStateToTest[i].pw>(1.001*globals.Constraints.err_max_pw[i])) { + report_error=average_power_limit; + } + } + } + + } + /* ------------------------------- */ + + /* --- check minimum delay ------- */ + if (globals.Flash.min_delay[i] != 0.0) { + /* use programmed limit, if non-zero */ + globals.Constraints.err_min_delay[i]=globals.Flash.min_delay[i]; + } else { + /* otherwise, assume delay has equal +/- range */ + globals.Constraints.err_min_delay[i]=-globals.Flash.max_delay[i]; + + /* for dual-delay units, positive delay only */ + if ((globals.Flash.ChanKey_delay?globals.Flash.channels:1)>1) { + globals.Constraints.err_min_delay[i]=0.0; + } + } + + if ( (globals.Constraints.err_min_delay[i]>=0.0 && ChannelStateToTest[i].delay<(0.999*globals.Constraints.err_min_delay[i])) + || (globals.Constraints.err_min_delay[i]<0.0 && ChannelStateToTest[i].delay<(1.001*globals.Constraints.err_min_delay[i])) ) { + report_error=delay_lower_limit; + } + + if (ChannelStateToTest[i].trigger_source==source_internal) { + temp=-0.95/ChannelStateToTest[i].frequency; + if (temp>globals.Constraints.err_min_delay[i]) { + globals.Constraints.err_min_delay[i]=temp; + if ( (globals.Constraints.err_min_delay[i]>=0.0 && ChannelStateToTest[i].delay<(0.999*globals.Constraints.err_min_delay[i])) + || (globals.Constraints.err_min_delay[i]<0.0 && ChannelStateToTest[i].delay<(1.001*globals.Constraints.err_min_delay[i])) ) { + report_error=Delay_Exceeds_95Period; + } + } + } + + if (ChannelStateToTest[i].double_pulse==double_on) { + temp=ChannelStateToTest[i].pw; + if (temp>globals.Constraints.err_min_delay[i]) { + globals.Constraints.err_min_delay[i]=temp; + if ( (globals.Constraints.err_min_delay[i]>=0.0 && ChannelStateToTest[i].delay<(0.999*globals.Constraints.err_min_delay[i])) + || (globals.Constraints.err_min_delay[i]<0.0 && ChannelStateToTest[i].delay<(1.001*globals.Constraints.err_min_delay[i])) ) { + report_error=PW_Exceeds_Double_Separation; + } + } + } + /* ------------------------------- */ + + /* --- check maximum delay ------- */ + globals.Constraints.err_max_delay[i]=globals.Flash.max_delay[i]; + + if ( (globals.Constraints.err_max_delay[i]>=0.0 && ChannelStateToTest[i].delay>(1.001*globals.Constraints.err_max_delay[i])) + || (globals.Constraints.err_max_delay[i]<0.0 && ChannelStateToTest[i].delay>(0.999*globals.Constraints.err_max_delay[i])) ) { + report_error=delay_upper_limit; + } + + if (ChannelStateToTest[i].trigger_source==source_internal) { + temp=0.95/ChannelStateToTest[i].frequency; + if (temp=0.0 && ChannelStateToTest[i].delay>(1.001*globals.Constraints.err_max_delay[i])) + || (globals.Constraints.err_max_delay[i]<0.0 && ChannelStateToTest[i].delay>(0.999*globals.Constraints.err_max_delay[i])) ) { + report_error=Delay_Exceeds_95Period; + } + } + + if (ChannelStateToTest[i].double_pulse==double_on) { + temp=(0.95/ChannelStateToTest[i].frequency)-ChannelStateToTest[i].pw; + if (temp=0.0 && ChannelStateToTest[i].delay>(1.001*globals.Constraints.err_max_delay[i])) + || (globals.Constraints.err_max_delay[i]<0.0 && ChannelStateToTest[i].delay>(0.999*globals.Constraints.err_max_delay[i])) ) { + report_error=Double_Separation_Too_Large; + } + } + } + } + /* ------------------------------- */ + + /* disable amplitude checks if amplitude calibration is in progress */ + if (!globals.extended_ampl_min_max) { + + globals.Constraints.err_max_vcc1[i]=globals.Flash.vcc1_max[i]; + globals.Constraints.err_max_vcc2[i]=globals.Flash.vcc2_max[i]; + globals.Constraints.err_max_vlogic[i]=ChannelStateToTest[0].vcc1; + globals.Constraints.err_min_vcc1[i]=0.0; + globals.Constraints.err_min_vcc2[i]=globals.Flash.vcc2_min[i]; + globals.Constraints.err_min_vlogic[i]=0.0; + if ( ChannelStateToTest[i].vcc1>(1.001*globals.Constraints.err_max_vcc1[i])) { + report_error=amplitude_upper_limit; + } + if ( ChannelStateToTest[i].vcc2>(1.001*globals.Constraints.err_max_vcc2[i])) { + report_error=amplitude_upper_limit; + } + if ( ChannelStateToTest[i].vlogic>(1.001*globals.Constraints.err_max_vlogic[i])) { + report_error=amplitude_upper_limit; + } + if ( ChannelStateToTest[i].vcc1=0.0 && ChannelStateToTest[i].amplitude<(0.999*globals.Constraints.err_min_ampl[i])) + || (globals.Constraints.err_min_ampl[i]<0.0 && ChannelStateToTest[i].amplitude<(1.001*globals.Constraints.err_min_ampl[i])) ) { + report_error=amplitude_lower_limit; + } + + temp=globals.Flash.min_vout[i]-ChannelStateToTest[i].offset; + if (temp>globals.Constraints.err_min_ampl[i]) { + globals.Constraints.err_min_ampl[i]=temp; + if ( (globals.Constraints.err_min_ampl[i]>=0.0 && ChannelStateToTest[i].amplitude<(0.999*globals.Constraints.err_min_ampl[i])) + || (globals.Constraints.err_min_ampl[i]<0.0 && ChannelStateToTest[i].amplitude<(1.001*globals.Constraints.err_min_ampl[i])) ) { + report_error=ampl_plus_os_lower_limit; + } + } + + /* ------------------------------- */ + + + /* --- check intermediate amplitude --- */ + if (globals.Flash.ampl_min_max_only[i]) + + if ( !(fabs(ChannelStateToTest[i].amplitude - globals.Flash.min_ampl[i] ) < globals.Flash.ampl_zero_equiv[i] ) + && + !(fabs(ChannelStateToTest[i].amplitude - globals.Flash.max_ampl[i]) < globals.Flash.ampl_zero_equiv[i] ) + ) + + { + report_error=amplitude_confined_values; + } + /* ------------------------------- */ + + + + /* --- check maximum amplitude --- */ + globals.Constraints.err_max_ampl[i]=globals.Flash.max_ampl[i]; + if ( (globals.Constraints.err_max_ampl[i]>=0.0 && ChannelStateToTest[i].amplitude>(1.001*globals.Constraints.err_max_ampl[i])) + || (globals.Constraints.err_max_ampl[i]<0.0 && ChannelStateToTest[i].amplitude>(0.999*globals.Constraints.err_max_ampl[i])) ) { + report_error=amplitude_upper_limit; + } + + temp = sqrt(globals.Flash.max_peak_power[i] * ChannelStateToTest[i].load_type); + if ((temp > 0.0) && (temp < globals.Constraints.err_max_ampl[i])) { + globals.Constraints.err_max_ampl[i] = temp; + if (-temp > globals.Constraints.err_min_ampl[i]) { + globals.Constraints.err_min_ampl[i] = -temp; + } + + if ((1.001*globals.Constraints.err_max_ampl[i]) < fabs(ChannelStateToTest[i].amplitude)) { + report_error=peak_power_limit; + } + } + + if (ChannelStateToTest[i].trigger_source==source_internal) { + temp = sqrt(globals.Flash.max_avg_power[i] * ChannelStateToTest[i].load_type / (ChannelStateToTest[i].pw * ChannelStateToTest[i].frequency)); + if ((temp > 0.0) && (temp < globals.Constraints.err_max_ampl[i])) { + globals.Constraints.err_max_ampl[i] = temp; + if (-temp > globals.Constraints.err_min_ampl[i]) { + globals.Constraints.err_min_ampl[i] = -temp; + } + + if ((1.001*globals.Constraints.err_max_ampl[i]) < fabs(ChannelStateToTest[i].amplitude)) { + report_error=average_power_limit; + } + } + } + + temp=globals.Flash.max_vout[i]-ChannelStateToTest[i].offset; + if (temp=0.0 && ChannelStateToTest[i].amplitude>(1.001*globals.Constraints.err_max_ampl[i])) + || (globals.Constraints.err_max_ampl[i]<0.0 && ChannelStateToTest[i].amplitude>(0.999*globals.Constraints.err_max_ampl[i])) ) { + report_error=ampl_plus_os_upper_limit; + } + } + + if (globals.Flash.min_pw[i] > 0.0) { + /* Check average amplitude */ + if ((globals.Flash.max_avg_ampl[i]) > 0.0 && (fabs(ChannelStateToTest[i].amplitude)) > 0.0) { + temp=100.0 * globals.Flash.max_avg_ampl[i] / (ChannelStateToTest[i].frequency * ChannelStateToTest[i].pw * duty_scale); + if (temp=0.0 && ChannelStateToTest[i].amplitude>(1.001*globals.Constraints.err_max_ampl[i])) + || (globals.Constraints.err_max_ampl[i]<0.0 && ChannelStateToTest[i].amplitude>(0.999*globals.Constraints.err_max_ampl[i])) ) { + report_error=Average_Amplitude_Too_High; + } + } + } + + duty_cycle=ChannelStateToTest[i].pw*ChannelStateToTest[i].frequency*100; /* calculate duty cycle */ + if (ChannelStateToTest[i].polarity!=pol_norm) { + duty_cycle=100-duty_cycle; /* account for inversion */ + } + + if (duty_cycle>(100.0*ampl_fixed_max_duty/duty_scale)) + /* set at crossover voltage */ + { + temp=globals.Flash.duty_ampl[i]; + + if (temp=0.0 && ChannelStateToTest[i].amplitude>(1.001*globals.Constraints.err_max_ampl[i])) + || (globals.Constraints.err_max_ampl[i]<0.0 && ChannelStateToTest[i].amplitude>(0.999*globals.Constraints.err_max_ampl[i])) + ) + && (duty_cycle > 1.001*(100.0*max_duty_high_ampl/duty_scale)) + ) { + report_error=duty_cycle_upper_limit; + } + } + } + + } + + /* ------------------------------- */ + + + if ((globals.Flash.voltage_offset_enabled[i]) || (globals.Flash.current_offset_enabled[i])) { + /* --- check minimum offset ------ */ + globals.Constraints.err_min_offset[i]=globals.Flash.min_offset[i]; + + if ( (globals.Constraints.err_min_offset[i]>=0.0 && ChannelStateToTest[i].offset<(0.999*globals.Constraints.err_min_offset[i])) + || (globals.Constraints.err_min_offset[i]<0.0 && ChannelStateToTest[i].offset<(1.001*globals.Constraints.err_min_offset[i])) ) { + report_error=offset_lower_limit; + } + + temp=globals.Flash.min_vout[i]-ChannelStateToTest[i].amplitude; + if (temp>globals.Constraints.err_min_offset[i]) { + globals.Constraints.err_min_offset[i]=temp; + if ( (globals.Constraints.err_min_offset[i]>=0.0 && ChannelStateToTest[i].offset<(0.999*globals.Constraints.err_min_offset[i])) + || (globals.Constraints.err_min_offset[i]<0.0 && ChannelStateToTest[i].offset<(1.001*globals.Constraints.err_min_offset[i])) ) { + report_error=ampl_plus_os_lower_limit; + } + } + + /* 1011 models: high level of PG-P output must remain positive */ + if (globals.Flash.ampl_coupled_to_os[i]) { + if (ChannelStateToTest[i].amplitude>globals.Flash.ampl_zero_equiv[i]) { + temp=-ChannelStateToTest[i].amplitude; + if (temp>globals.Constraints.err_min_offset[i]) { + globals.Constraints.err_min_offset[i]=temp; + if (ChannelStateToTest[i].offset<=globals.Constraints.err_min_offset[i]) { + report_error=Coupled_OS_Ampl_Error; + } + } + } + } + + + /* ------------------------------- */ + + + /* --- check maximum offset ------ */ + globals.Constraints.err_max_offset[i]=globals.Flash.max_offset[i]; + + if ( (globals.Constraints.err_max_offset[i]>=0.0 && ChannelStateToTest[i].offset>(1.001*globals.Constraints.err_max_offset[i])) + || (globals.Constraints.err_max_offset[i]<0.0 && ChannelStateToTest[i].offset>(0.999*globals.Constraints.err_max_offset[i])) ) { + report_error=offset_upper_limit; + } + + temp=globals.Flash.max_vout[i]-ChannelStateToTest[i].amplitude; + if (temp=0.0 && ChannelStateToTest[i].offset>(1.001*globals.Constraints.err_max_offset[i])) + || (globals.Constraints.err_max_offset[i]<0.0 && ChannelStateToTest[i].offset>(0.999*globals.Constraints.err_max_offset[i])) ) { + report_error=ampl_plus_os_upper_limit; + } + } + + /* 1011 models: low level of PG-N output must remain negative */ + if (globals.Flash.ampl_coupled_to_os[i]) { + if (ChannelStateToTest[i].amplitude<-globals.Flash.ampl_zero_equiv[i]) { + temp=-ChannelStateToTest[i].amplitude; + if (temp=globals.Constraints.err_max_offset[i]) { + report_error=Coupled_OS_Ampl_Error; + } + } + } + } + + /* ------------------------------- */ + } + } + + + /* --- check for nonsensical negatives ------ */ + if ( ChannelStateToTest[i].frequency<0.0 + || ((ChannelStateToTest[i].pw<0.0) && (globals.Flash.min_pw[i] > 0.0)) + || ChannelStateToTest[i].zout<0) { + report_error=Negative_Not_Allowed; + } + /* ------------------------------- */ + + + + /* --- check burst count settings --- */ + + if (globals.Flash.max_burst_count[i]>1) { + + /* --- check minimum setting --- */ + if ( (!globals.Flash.burst_func[i] && ChannelStateToTest[i].burst_count<1) + || + (globals.Flash.burst_func[i] && ChannelStateToTest[i].burst_count<0)) { + report_error=IllegalParameter; + } + + /* --- check maximum setting --- */ + + globals.Constraints.err_max_burst_count[i]=globals.Flash.max_burst_count[i]; + + if (ChannelStateToTest[i].burst_count>globals.Constraints.err_max_burst_count[i]) { + report_error=max_burst_count_error; + } + + + if (!globals.Flash.burst_func[i]) { + if (globals.Flash.min_pw[i] > 0.0) { + temp = (ChannelStateToTest[i].frequency * ampl_fixed_max_duty) / + (ChannelStateToTest[i].pw * 100.0); + + if (temp < (float) globals.Constraints.err_max_burst_count[i]) { + globals.Constraints.err_max_burst_count[i] = (int) temp; + if ( (ChannelStateToTest[i].burst_count>globals.Constraints.err_max_burst_count[i]) + && (ChannelStateToTest[i].burst_count>1)) { + report_error=max_burst_count_error; + } + } + + + temp = (1.0/ChannelStateToTest[i].frequency) / + (ChannelStateToTest[i].pw+ChannelStateToTest[i].burst_time); + + if (temp < (float) globals.Constraints.err_max_burst_count[i]) { + globals.Constraints.err_max_burst_count[i] = (int) temp; + if ( (ChannelStateToTest[i].burst_count>globals.Constraints.err_max_burst_count[i]) + && (ChannelStateToTest[i].burst_count>1)) { + report_error=Burst_Exceeds_Period; + } + } + } + + + /* --- check minimum burst gap settings --- */ + + globals.Constraints.err_min_burst_time[i]=globals.Flash.min_burst_gap[i]; + if ( (ChannelStateToTest[i].burst_count>1) + && (ChannelStateToTest[i].burst_time<(0.999*globals.Constraints.err_min_burst_time[i]))) { + report_error=min_burst_gap_error; + } + + + /* --- check minimum burst period settings --- */ + + if (globals.Flash.min_pw[i] > 0.0) { + temp = globals.Flash.min_burst_per[i] - ChannelStateToTest[i].pw; + if (temp > globals.Constraints.err_min_burst_time[i]) { + globals.Constraints.err_min_burst_time[i] = temp; + if ( (ChannelStateToTest[i].burst_count>1) + && (ChannelStateToTest[i].burst_time<(0.999*globals.Constraints.err_min_burst_time[i]))) { + report_error=min_burst_period_error; + } + } + + /* only report error when burst count is > 1, otherwise it gets annoying */ + temp = ChannelStateToTest[i].pw * (100.0/globals.Flash.max_burst_duty[i] - 1.0); + if (temp > globals.Constraints.err_min_burst_time[i]) { + globals.Constraints.err_min_burst_time[i] = temp; + if ( (ChannelStateToTest[i].burst_time<(0.999*globals.Constraints.err_min_burst_time[i])) + && (ChannelStateToTest[i].burst_count>1)) { + report_error=burst_duty_error; + } + } + } + + /* --- check maximum burst gap settings --- */ + + globals.Constraints.err_max_burst_time[i]=globals.Flash.max_burst_gap[i]; + if ( (ChannelStateToTest[i].burst_count>1) + && (ChannelStateToTest[i].burst_time>(1.001*globals.Constraints.err_max_burst_time[i]))) { + report_error=max_burst_gap_error; + } + + } + } + + /* --- check rise time settings --- */ + /* disable amplitude checks if calibration is in progress */ + if (!globals.Flash.fixed_rise_time[i]) + if (!globals.extended_ampl_min_max) { + globals.Constraints.err_min_rise_time[i]=globals.Flash.min_rise_time[i]; + if (ChannelStateToTest[i].rise_time<(0.999*globals.Constraints.err_min_rise_time[i])) { + report_error=min_rise_time_error; + } + + globals.Constraints.err_max_rise_time[i]=globals.Flash.max_rise_time[i]; + if (ChannelStateToTest[i].rise_time>(1.001*globals.Constraints.err_max_rise_time[i])) { + report_error=max_rise_time_error; + } + } + + /* --- check slew settings --- */ + /* disable amplitude checks if calibration is in progress */ + if (globals.Flash.curr_slew[i]) + if (!globals.extended_ampl_min_max) { + globals.Constraints.err_min_slew[i]=globals.Flash.min_slew[i]; + if (ChannelStateToTest[i].slew<(0.999*globals.Constraints.err_min_slew[i])) { + report_error=min_slew_error; + } + + globals.Constraints.err_max_slew[i]=globals.Flash.max_slew[i]; + if (ChannelStateToTest[i].slew>(1.001*globals.Constraints.err_max_slew[i])) { + report_error=max_slew_error; + } + } + + /* --- check resistance settings --- */ + + if (globals.Flash.switchable_load[i]) { + globals.Constraints.err_min_load_type[i]=globals.Flash.low_load_type[i]; + if ((ChannelStateToTest[i].trigger_source==source_internal) && (duty_cycle > max_duty_this_ampl)) { + globals.Constraints.err_min_load_type[i] *= duty_cycle / max_duty_this_ampl; + } + if (ChannelStateToTest[i].load_type<(0.999*globals.Constraints.err_min_load_type[i])) { + report_error=min_load_type_error; + } + } + + if (globals.Flash.max_peak_power[i] > 0.0) { + temp = ChannelStateToTest[i].amplitude * ChannelStateToTest[i].amplitude / globals.Flash.max_peak_power[i]; + if (temp > globals.Constraints.err_min_load_type[i]) { + globals.Constraints.err_min_load_type[i] = temp; + if (ChannelStateToTest[i].load_type<(0.999*globals.Constraints.err_min_load_type[i])) { + report_error=peak_power_limit; + } + } + } + + if (ChannelStateToTest[i].trigger_source==source_internal) { + if (globals.Flash.max_avg_power[i] > 0.0) { + temp = (ChannelStateToTest[i].amplitude * ChannelStateToTest[i].amplitude * ChannelStateToTest[i].pw * ChannelStateToTest[i].frequency) / globals.Flash.max_avg_power[i]; + if (temp > globals.Constraints.err_min_load_type[i]) { + globals.Constraints.err_min_load_type[i] = temp; + if (ChannelStateToTest[i].load_type<(0.999*globals.Constraints.err_min_load_type[i])) { + report_error=average_power_limit; + } + } + } + } + + globals.Constraints.err_max_load_type[i]=1.0*globals.Flash.high_load_type[i]; + if (ChannelStateToTest[i].load_type>(1.001*globals.Constraints.err_max_load_type[i])) { + report_error=max_load_type_error; + } + + /* --- check soft_current_limit settings --- */ + if (globals.Flash.soft_current_limit_enabled[i]) { + globals.Constraints.err_min_soft_current_limit[i]=globals.Flash.min_soft_current_limit[i]; + if (ChannelStateToTest[i].soft_current_limit<(0.999*globals.Constraints.err_min_soft_current_limit[i])) { + report_error=min_soft_current_limit_error; + } + + globals.Constraints.err_max_soft_current_limit[i]=globals.Flash.max_soft_current_limit[i]; + + temp=globals.Flash.current_limit_pulse_mode[i];; + if (temp < globals.Constraints.err_max_soft_current_limit[i]) { + globals.Constraints.err_max_soft_current_limit[i] = temp; + } + + if (ChannelStateToTest[i].func_mode==dc_mode_on) { + temp=globals.Flash.current_limit_dc_mode[i]; + if (temp < globals.Constraints.err_max_soft_current_limit[i]) { + globals.Constraints.err_max_soft_current_limit[i] = temp; + } + } + + if (ChannelStateToTest[i].soft_current_limit>(1.001*globals.Constraints.err_max_soft_current_limit[i])) { + report_error=max_soft_current_limit_error; + } + } + + + /* --- done all per-channel checking ---- */ + } + + return report_error; + +} + diff --git a/error_utils.h b/error_utils.h index ac9a8c9..3153c0a 100644 --- a/error_utils.h +++ b/error_utils.h @@ -1,89 +1,13 @@ #ifndef ERROR_UTILS_H_ #define ERROR_UTILS_H_ +#include "globals.h" #include -/* error codes */ -#define OK 0 -#define Unrecognized 1 -#define SyntaxError 2 -#define OutOfRange 3 -#define UnknownUnits 4 -#define Overload_Detected 5 -#define duty_cycle_upper_limit 6 -#define AB_Mode_Error 7 -#define Valid_For_RS232_TELNET_Only 8 -#define PW_Exceeds_Period 9 -#define Delay_Exceeds_95Period 10 -#define Double_Separation_Too_Large 11 -#define freq_lower_limit 12 -#define freq_upper_limit 13 -#define pw_lower_limit 14 -#define pw_upper_limit 15 -#define delay_upper_limit 16 -#define delay_lower_limit 17 -#define amplitude_lower_limit 18 -#define amplitude_upper_limit 19 -#define offset_lower_limit 20 -#define offset_upper_limit 21 -#define ampl_plus_os_lower_limit 22 -#define ampl_plus_os_upper_limit 23 -#define DutyTriggerError 24 -#define PW_Exceeds_Double_Separation 25 -#define queue_overflow 26 -#define query_error_interrupted 27 -#define IllegalParameter 28 -#define Negative_Not_Allowed 29 -#define query_error_unterminated 30 -#define Overtemp_Detected 31 -#define Overvolt_Detected 32 -#define Device_Specific_Aux_Error_Detected 33 -#define InvalidChannel 34 -#define AsyncModeDisabled 36 -#define CalibrationPercentError 37 -#define NeedNonZeroAmpl 38 -#define amplitude_confined_values 40 -#define HardwareError 41 -#define CalibrationZeroError 42 -#define CalibrationMinMaxError 43 -#define CalibrationClosenessError 44 -#define CalibrationTimingProblem 45 -#define CalibrationRangeError 46 -#define CalibrationPolarityError 47 -#define Coupled_OS_Ampl_Error 48 -#define PW_Distort_Error 49 -#define burst_duty_error 50 -#define min_burst_period_error 51 -#define min_burst_gap_error 52 -#define max_burst_gap_error 53 -#define max_burst_count_error 54 -#define Burst_Exceeds_Period 55 -#define password_change_error 56 -#define min_rise_time_error 57 -#define max_rise_time_error 58 -#define min_soft_current_limit_error 59 -#define max_soft_current_limit_error 60 -#define Average_Amplitude_Too_High 61 -#define Route_Range_Error 64 -#define Soft_Limit_Exceeded 65 -#define min_slew_error 67 -#define max_slew_error 68 -#define min_load_type_error 69 -#define max_load_type_error 70 -#define peak_power_limit 71 -#define average_power_limit 72 -#define SelfCalError 73 -#define NetworkNotFound 74 - -// BEGIN CUSTOM DEFINES -#define LCD_cols 32 -#define YES 1 -#define NO 0 -// END CUSTOM DEFINES - void get_error_text(gchar** response, int error_num); void queue_error_from_parser(gchar** response, int error_num); void queue_error_and_get_text(gchar** response, int error_num); void Error_Remove_From_Queue(void); +int Error_check(ChannelStruct ChannelStateToTest[max_channels]); #endif diff --git a/globals.h b/globals.h index b39cf86..c892b37 100644 --- a/globals.h +++ b/globals.h @@ -4,7 +4,6 @@ #include #include #include -#include "error_utils.h" #define DEBUG_ON - uncomment this to have debug messages @@ -14,6 +13,85 @@ #define g_print_debug(...) {} #endif + +/* error codes */ +#define OK 0 +#define Unrecognized 1 +#define SyntaxError 2 +#define OutOfRange 3 +#define UnknownUnits 4 +#define Overload_Detected 5 +#define duty_cycle_upper_limit 6 +#define AB_Mode_Error 7 +#define Valid_For_RS232_TELNET_Only 8 +#define PW_Exceeds_Period 9 +#define Delay_Exceeds_95Period 10 +#define Double_Separation_Too_Large 11 +#define freq_lower_limit 12 +#define freq_upper_limit 13 +#define pw_lower_limit 14 +#define pw_upper_limit 15 +#define delay_upper_limit 16 +#define delay_lower_limit 17 +#define amplitude_lower_limit 18 +#define amplitude_upper_limit 19 +#define offset_lower_limit 20 +#define offset_upper_limit 21 +#define ampl_plus_os_lower_limit 22 +#define ampl_plus_os_upper_limit 23 +#define DutyTriggerError 24 +#define PW_Exceeds_Double_Separation 25 +#define queue_overflow 26 +#define query_error_interrupted 27 +#define IllegalParameter 28 +#define Negative_Not_Allowed 29 +#define query_error_unterminated 30 +#define Overtemp_Detected 31 +#define Overvolt_Detected 32 +#define Device_Specific_Aux_Error_Detected 33 +#define InvalidChannel 34 +#define AsyncModeDisabled 36 +#define CalibrationPercentError 37 +#define NeedNonZeroAmpl 38 +#define amplitude_confined_values 40 +#define HardwareError 41 +#define CalibrationZeroError 42 +#define CalibrationMinMaxError 43 +#define CalibrationClosenessError 44 +#define CalibrationTimingProblem 45 +#define CalibrationRangeError 46 +#define CalibrationPolarityError 47 +#define Coupled_OS_Ampl_Error 48 +#define PW_Distort_Error 49 +#define burst_duty_error 50 +#define min_burst_period_error 51 +#define min_burst_gap_error 52 +#define max_burst_gap_error 53 +#define max_burst_count_error 54 +#define Burst_Exceeds_Period 55 +#define password_change_error 56 +#define min_rise_time_error 57 +#define max_rise_time_error 58 +#define min_soft_current_limit_error 59 +#define max_soft_current_limit_error 60 +#define Average_Amplitude_Too_High 61 +#define Route_Range_Error 64 +#define Soft_Limit_Exceeded 65 +#define min_slew_error 67 +#define max_slew_error 68 +#define min_load_type_error 69 +#define max_load_type_error 70 +#define peak_power_limit 71 +#define average_power_limit 72 +#define SelfCalError 73 +#define NetworkNotFound 74 + + +#define LCD_cols 32 +#define YES 1 +#define NO 0 + + #define error_queue_length 512 #define max_commands_in_input 12 #define max_output_length 512 @@ -126,6 +204,10 @@ #define rs232_echo_off 0x00 #define rs232_echo_on 0x20 + +#define smallest_allowed_number 1.0e-18 + + long sec_timer (void); typedef struct { @@ -596,6 +678,7 @@ typedef struct { int ques_enable_register; /* for stat:enable command */ int flash_writes_suspended; long startup_timer_value; + long last_activity_at[max_channels]; } GlobalStruct; diff --git a/string_utils.h b/string_utils.h index 9cb8c4f..c090000 100644 --- a/string_utils.h +++ b/string_utils.h @@ -3,8 +3,6 @@ #include -#define smallest_allowed_number 1.0e-18 - void Float_To_Text(int decimal_digits,float number_in, gchar** text_out); gboolean String_is_it_numeric(char *parameter); -- cgit