summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael J. Chudobiak <mjc@avtechpulse.com>2012-08-23 14:49:16 -0400
committerMichael J. Chudobiak <mjc@avtechpulse.com>2012-08-23 14:49:16 -0400
commit8ca8f7fbf06ac9ce5f2817e31d6bae330f243aa1 (patch)
treec4c5f0f70234d8dc3a6e3fc4995af0053e144035
parent913fc3cf402788ec671102f76ad27dc9436be6f6 (diff)
added full error checker
-rw-r--r--CMakeLists.txt2
-rw-r--r--device-functions.c20
-rw-r--r--device-functions.h4
-rw-r--r--dummy_functions.c1
-rw-r--r--dummy_functions.h1
-rw-r--r--error_utils.c902
-rw-r--r--error_utils.h80
-rw-r--r--globals.h85
-rw-r--r--string_utils.h2
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 <glib.h>
/*** 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<max_channels; ++i) {
+ TestState[i]=globals.ChannelState[i];
+ }
+ TestState[channel].frequency=set_freq;
+ if ((check_valid=Error_check(TestState))) {
+ return check_valid;
+ }
+ }
globals.ChannelState[channel].frequency=set_freq;
diff --git a/device-functions.h b/device-functions.h
index 09b7376..f3a28ba 100644
--- a/device-functions.h
+++ b/device-functions.h
@@ -1,6 +1,10 @@
#ifndef DEVICE_FUNCTIONS_H_
#define DEVICE_FUNCTIONS_H_
+
#include "globals.h"
+#include <glib.h>
+
+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 <string.h>
#include <glib/gprintf.h>
+#include <math.h>
#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; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].frequency=ChannelStateToTest[0].frequency;
+ }
+ if (!globals.Flash.ChanKey_delay) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].delay=ChannelStateToTest[0].delay;
+ }
+ if (!globals.Flash.ChanKey_pw) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].pw=ChannelStateToTest[0].pw;
+ }
+ if (!globals.Flash.ChanKey_amplitude) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].amplitude=ChannelStateToTest[0].amplitude;
+ }
+ if (!globals.Flash.ChanKey_offset) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].offset=ChannelStateToTest[0].offset;
+ }
+
+ if (!globals.Flash.ChanKey_Curr_Mon_value) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].Curr_Mon_value=ChannelStateToTest[0].Curr_Mon_value;
+ }
+ if (!globals.Flash.ChanKey_Curr_Mon_offset) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].Curr_Mon_offset=ChannelStateToTest[0].Curr_Mon_offset;
+ }
+
+ if (!globals.Flash.ChanKey_zout) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].zout=ChannelStateToTest[0].zout;
+ }
+ if (!globals.Flash.ChanKey_hold_setting) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].hold_setting=ChannelStateToTest[0].hold_setting;
+ }
+ if (!globals.Flash.ChanKey_double_pulse) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].double_pulse=ChannelStateToTest[0].double_pulse;
+ }
+ if (!globals.Flash.ChanKey_ab_mode) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].ab_mode=ChannelStateToTest[0].ab_mode;
+ }
+ if (!globals.Flash.ChanKey_func_mode) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].func_mode=ChannelStateToTest[0].func_mode;
+ }
+ if (!globals.Flash.ChanKey_polarity) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].polarity=ChannelStateToTest[0].polarity;
+ }
+ if (!globals.Flash.ChanKey_output_state) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].output_state=ChannelStateToTest[0].output_state;
+ }
+ if (!globals.Flash.ChanKey_gate_type) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].gate_type=ChannelStateToTest[0].gate_type;
+ }
+ if (!globals.Flash.ChanKey_trigger_source) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].trigger_source=ChannelStateToTest[0].trigger_source;
+ }
+ if (!globals.Flash.ChanKey_amp_mode) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].amp_mode=ChannelStateToTest[0].amp_mode;
+ }
+ if (!globals.Flash.ChanKey_gate_level) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].gate_level=ChannelStateToTest[0].gate_level;
+ }
+ if (!globals.Flash.ChanKey_load_type) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].load_type=ChannelStateToTest[0].load_type;
+ }
+ if (!globals.Flash.ChanKey_test_delay_mode) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].test_delay_mode=ChannelStateToTest[0].test_delay_mode;
+ }
+ if (!globals.Flash.ChanKey_os_mode) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].os_mode=ChannelStateToTest[0].os_mode;
+ }
+ if (!globals.Flash.ChanKey_Burst_Count) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].burst_count=ChannelStateToTest[0].burst_count;
+ }
+ if (!globals.Flash.ChanKey_Burst_Time) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].burst_time=ChannelStateToTest[0].burst_time;
+ }
+ if (!globals.Flash.ChanKey_rise_time) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].rise_time=ChannelStateToTest[0].rise_time;
+ }
+ if (!globals.Flash.ChanKey_slew) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].slew=ChannelStateToTest[0].slew;
+ }
+ if (!globals.Flash.ChanKey_current_limit) for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].soft_current_limit=ChannelStateToTest[0].soft_current_limit;
+ }
+ for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].vcc1=ChannelStateToTest[0].vcc1;
+ }
+ for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].vcc2=ChannelStateToTest[0].vcc2;
+ }
+ for (i=1; i<num_of_chan; ++i) {
+ ChannelStateToTest[i].vlogic=ChannelStateToTest[0].vlogic;
+ }
+ }
+
+
+ report_error=OK;
+
+ for (i=0; i<num_of_chan; ++i) {
+ /* Must be changing a setting */
+ globals.last_activity_at[i] = sec_timer ();
+
+ /* ignore errors if it is in programming mode */
+ if (globals.Flash.fully_programmed != All_Programmed) {
+ return OK;
+ }
+
+ if (globals.do_check_settings==NO) {
+ return OK;
+ }
+
+ /* check for settings that would cause divide-by-zero errors in the error-checking routine */
+ if (ChannelStateToTest[i].frequency<smallest_allowed_number) {
+ return freq_lower_limit;
+ }
+
+ if (ChannelStateToTest[i].pw<smallest_allowed_number
+ && globals.Flash.min_pw[i]>0.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<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=Delay_Exceeds_95Period;
+ }
+ }
+ }
+
+ if (globals.Flash.min_pw[i] > 0.0) {
+ temp=1/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=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<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=Burst_Exceeds_Period;
+ }
+ }
+ }
+
+ if (ChannelStateToTest[i].polarity==pol_norm) {
+ temp=(1/ChannelStateToTest[i].pw)*(ampl_fixed_max_duty/duty_scale);
+ 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=duty_cycle_upper_limit;
+ }
+ }
+ }
+
+ if (ChannelStateToTest[i].double_pulse==double_on) {
+ temp=0.95/(ChannelStateToTest[i].pw+fabs(ChannelStateToTest[i].delay));
+ 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=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<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_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<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=PW_Exceeds_Double_Separation;
+ }
+ }
+ }
+
+ if (ChannelStateToTest[i].trigger_source==source_internal) {
+ temp=1/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=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<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=Burst_Exceeds_Period;
+ }
+ }
+ }
+
+ if (ChannelStateToTest[i].polarity==pol_norm) {
+ temp=(1/ChannelStateToTest[i].frequency)*(ampl_fixed_max_duty/duty_scale);
+ 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=duty_cycle_upper_limit;
+ }
+ }
+ }
+
+ if (ChannelStateToTest[i].double_pulse==double_on) {
+ temp=(0.95/ChannelStateToTest[i].frequency)-ChannelStateToTest[i].delay;
+ 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=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<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_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<globals.Constraints.err_max_delay[i]) {
+ globals.Constraints.err_max_delay[i]=temp;
+ 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_Exceeds_95Period;
+ }
+ }
+
+ if (ChannelStateToTest[i].double_pulse==double_on) {
+ temp=(0.95/ChannelStateToTest[i].frequency)-ChannelStateToTest[i].pw;
+ if (temp<globals.Constraints.err_max_delay[i]) {
+ globals.Constraints.err_max_delay[i]=temp;
+ 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=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<globals.Constraints.err_min_vcc1[i]) {
+ report_error=amplitude_lower_limit;
+ }
+ if ( ChannelStateToTest[i].vcc2<globals.Constraints.err_min_vcc2[i]) {
+ report_error=amplitude_lower_limit;
+ }
+ if ( ChannelStateToTest[i].vlogic<globals.Constraints.err_min_vlogic[i]) {
+ report_error=amplitude_lower_limit;
+ }
+
+
+ /* --- check minimum amplitude --- */
+ globals.Constraints.err_min_ampl[i]=globals.Flash.min_ampl[i];
+
+ 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=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<globals.Constraints.err_max_ampl[i]) {
+ globals.Constraints.err_max_ampl[i]=temp;
+ 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=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<globals.Constraints.err_max_ampl[i]) {
+ globals.Constraints.err_max_ampl[i]=temp;
+ 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=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<globals.Constraints.err_max_ampl[i]) {
+ globals.Constraints.err_max_ampl[i]=temp;
+ 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]))
+ )
+ && (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<globals.Constraints.err_max_offset[i]) {
+ globals.Constraints.err_max_offset[i]=temp;
+ 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=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]) {
+ globals.Constraints.err_max_offset[i]=temp;
+ if (ChannelStateToTest[i].offset>=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 <glib.h>
-/* 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 <stdio.h>
#include <string.h>
#include <stdlib.h>
-#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 <glib.h>
-#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);