/* START LIBRARY DESCRIPTION ********************************************* ERRCHK.LIB Copyright (c) 2006, Avtech Electrosystems Ltd. DESCRIPTION: Error-checking and reporting functions. SUPPORT LIB'S: END DESCRIPTION **********************************************************/ /*** BeginHeader Error_check */ #include <string.h> #include <glib/gprintf.h> #include <glib.h> #include <math.h> #include "globals.h" #include "lcd.h" #include "error_utils.h" #include "menus.h" #include "gpib.h" #include "device-functions.h" /*** EndHeader */ void set_gpib_error_flags (int error_num); void set_gpib_error_flags (int error_num) { if (error_num == OK) { return; } /* set the error flags in the GPIB ESR register right away */ switch (error_num) { case AsyncModeDisabled: case Unrecognized: case SyntaxError: case UnknownUnits: case InvalidChannel: case ThisShouldntHappen: case obsolete_feature: case config_too_large: case config_cant_be_negative: GPIB_Set_Command_Error(); break; case query_error_interrupted: case query_error_unterminated: GPIB_Set_Query_Error(); break; case Overload_Detected: case Overtemp_Detected: case Overvolt_Detected: case Device_Specific_Aux_Error_Detected: case queue_overflow: case CalibrationPercentError: case CalibrationZeroError: case CalibrationMinMaxError_ampl: case CalibrationMinMaxError_pw: case CalibrationMinMaxError_os: case CalibrationMinMaxError_freq: case CalibrationMinMaxError_delay: case CalibrationMinMaxError_burst: case CalibrationMinMaxError_rise: case CalibrationMinMaxError_slew: case CalibrationClosenessError: case CalibrationRangeError: case CalibrationPolarityError: case Soft_Limit_Exceeded: case SelfCalError: case NetworkNotFound: case Startup_Not_Finished: case GPIB_missing: case Between_0_and_10_Volts: GPIB_Set_Device_Dependent_Error(); break; default: GPIB_Set_Execution_Error(); break; } return; } void queue_error(int error_num); void queue_error(int error_num) { if (error_num == OK) { return; } set_gpib_error_flags (error_num); if (globals.Errors.number_of_errors<error_queue_length) { ++globals.Errors.number_of_errors; globals.Errors.error_queue[globals.Errors.number_of_errors]=error_num; } else { globals.Errors.error_queue[globals.Errors.number_of_errors]=queue_overflow; } return; } /*----------------------------------------------------------------------------------------------------------*/ void queue_error_and_get_text(gchar** response, int error_num) { g_assert (*response == NULL); if (error_num == OK) { return; } queue_error (error_num); get_error_text (response, error_num); return; } /*----------------------------------------------------------------------------------------------------------*/ void queue_error_from_parser(gchar** response, int error_num) { g_assert (*response == NULL); if (error_num == OK) { return; } queue_error_and_get_text(response, error_num); Show_Main_Menu(); return; } void queue_error_for_gpib_only(int error_num) { if (error_num == OK) { return; } queue_error(error_num); return; } void queue_error_and_display_on_LCD(int error_num) { if (error_num == OK) { return; } gchar* response = NULL; queue_error_and_get_text(&response, error_num); LCD_display_extended_message (response, TRUE, TRUE); g_free (response); } extern void send_message(gchar* message); void queue_and_broadcast_sensor_alarm(int error_num) { if (error_num == OK) { return; } gchar* response = NULL; queue_error_and_get_text(&response, error_num); LCD_display_extended_message (response, TRUE, TRUE); gchar *broadcast_str = g_strdup_printf ("%s\r\n> ", response); send_message(broadcast_str); g_free (broadcast_str); g_free (response); } /*----------------------------------------------------------------------------------------------------------*/ void Error_Remove_From_Queue(void) { int i; for (i=1; i<globals.Errors.number_of_errors; ++i) { globals.Errors.error_queue[i]=globals.Errors.error_queue[i+1]; } --globals.Errors.number_of_errors; /* error reported, so remove it from the error queue */ } void format_error_text (gchar **response, int error_type, char *in); void format_error_text (gchar **response, int error_type, char *in) { char* prefix = NULL; switch (error_type) { case 0: prefix = g_strdup("No error"); break; case -100: prefix=g_strdup("Command error"); break; case -102: prefix=g_strdup("Syntax error"); break; case -114: prefix=g_strdup("Command error"); break; case -131: prefix=g_strdup("Invalid suffix"); break; case -200: prefix=g_strdup("Execution error"); break; case -221: prefix=g_strdup("Settings conflict"); break; case -222: prefix=g_strdup("Data out of range"); break; case -224: prefix=g_strdup("Illegal parameter value"); break; case -240: prefix=g_strdup("Hardware error"); break; case -300: prefix=g_strdup("Device-specific error"); break; case -340: prefix=g_strdup("Calibration failed"); break; case -350: prefix=g_strdup("Queue overflow"); break; case -400: prefix=g_strdup("Query error"); break; default: prefix=g_strdup("System error"); break; } *response = g_strdup_printf("%d, \"%s; %s\"", error_type, prefix, in); g_free(prefix); } void get_error_text(gchar **response, int error_num) { switch (error_num) { case OK: format_error_text(response,0,""); break; case Unrecognized: format_error_text(response,-102,"Unrecognized command."); break; case AsyncModeDisabled: format_error_text(response,-102,"Async gating not available."); break; case SyntaxError: format_error_text(response,-100,"Recognized command, but improper syntax."); break; case InvalidChannel: format_error_text(response,-114,"Invalid channel suffix."); break; case OutOfRange: format_error_text(response,-222,"Too high or too low."); break; case Negative_Not_Allowed: format_error_text(response,-222,"Negative value not allowed."); break; case IllegalParameter: case rise_time_confined_values: case amplitude_confined_values: format_error_text(response,-224,"Not in list of allowed values."); break; case UnknownUnits: format_error_text(response,-131,"Unrecognized units."); break; case Route_Range_Error: format_error_text(response,-224,"Ranges are not supported."); break; case AB_Mode_Error: format_error_text(response,-221,"This PW mode is not valid for the current trigger mode."); break; case Valid_For_RS232_TELNET_Only: format_error_text(response,-221,"Command valid in RS232 or TELNET modes only."); break; case PW_Exceeds_Period: format_error_text(response,-221,"PW can not exceed period."); break; case Delay_Exceeds_95Period: format_error_text(response,-221,"Delay can not exceed 95% of period."); break; case NeedNonZeroAmpl: format_error_text(response,-222,"Amplitude must be non-zero."); break; case freq_lower_limit: format_error_text(response,-222,"PRF too low."); break; case freq_upper_limit: format_error_text(response,-222,"PRF too high."); break; case pw_lower_limit: format_error_text(response,-222,"PW too low."); break; case pw_upper_limit: format_error_text(response,-222,"PW too high."); break; case pw_rc_limit: format_error_text(response,-222,"PW exceeds RC limit."); break; case HVPS_Current_Too_High: format_error_text(response,-222,"HVPS current too high."); break; case max_rise_time_error: format_error_text(response,-222,"Rise time too high."); break; case min_rise_time_error: format_error_text(response,-222,"Rise time too low."); break; case max_slew_error: format_error_text(response,-222,"Slew rate too high."); break; case min_slew_error: format_error_text(response,-222,"Slew rate too low."); break; case max_load_type_error: format_error_text(response,-222,"Resistance too high."); break; case min_load_type_error: format_error_text(response,-222,"Duty cycle too high or load resistance too low."); break; case max_soft_current_limit_error: format_error_text(response,-222,"Current limit too high."); break; case min_soft_current_limit_error: format_error_text(response,-222,"Current limit too low."); break; case duty_cycle_upper_limit: format_error_text(response,-222,"Duty cycle too high."); break; case Average_Amplitude_Too_High: format_error_text(response,-222,"Average amplitude too high."); break; case delay_lower_limit: format_error_text(response,-222,"Delay too low."); break; case delay_upper_limit: format_error_text(response,-222,"Delay too high."); break; case amplitude_lower_limit: format_error_text(response,-222,"Amplitude too low."); break; case amplitude_upper_limit: format_error_text(response,-222,"Amplitude too high."); break; case amplitude_gap: format_error_text(response,-222,"Amplitude magnitude too low."); break; case peak_power_limit: format_error_text(response,-222,"Peak power too high."); break; case average_power_limit: format_error_text(response,-222,"Average power too high."); break; case offset_lower_limit: format_error_text(response,-222,"Offset too low."); break; case offset_upper_limit: format_error_text(response,-222,"Offset too high."); break; case ampl_plus_os_lower_limit: format_error_text(response,-222,"AMPL+OS too low."); break; case ampl_plus_os_upper_limit: format_error_text(response,-222,"AMPL+OS too high."); break; case DutyTriggerError: format_error_text(response,-221,"Duty cycle can not be set. Set PW instead."); break; case Double_Separation_Too_Small: format_error_text(response,-221,"Double pulse separation too small."); break; case Double_Separation_Too_Large: format_error_text(response,-221,"Double pulse separation too high."); break; case Cant_Do_Burst_and_Double: format_error_text(response,-221,"Can't use burst mode and double pulse mode at the same time."); break; case queue_overflow: format_error_text(response,-350,"Clear with *cls or syst:err."); break; case query_error_interrupted: format_error_text(response,-400,"Data lost in output buffer."); break; case query_error_unterminated: format_error_text(response,-400,"No data to send."); break; case Overload_Detected: format_error_text(response,-300,"Power supply overload detected. Output disabled."); break; case Overtemp_Detected: format_error_text(response,-300,globals.Flash.ot_error_message); break; case Overvolt_Detected: format_error_text(response,-300,globals.Flash.ov_error_message); break; case Soft_Limit_Exceeded: format_error_text(response,-300,"Monitor current limit exceeded. Output disabled."); break; case Device_Specific_Aux_Error_Detected: format_error_text(response,-300,globals.Flash.aux_error_message); break; case CalibrationPercentError: format_error_text(response,-340,"Percent change is too large."); break; case Between_0_and_10_Volts: format_error_text(response,-340,"Must be between 0.0 and 10.0."); break; case CalibrationPolarityError: format_error_text(response,-340,"Old and new polarities disagree."); break; case CalibrationZeroError: format_error_text(response,-340,"Zero point can not be changed."); break; case CalibrationMinMaxError_ampl: format_error_text(response,-340,"Would prevent operation at the minimum or maximum amplitude."); break; case CalibrationMinMaxError_pw: format_error_text(response,-340,"Would prevent operation at the minimum or maximum pulse width."); break; case CalibrationMinMaxError_os: format_error_text(response,-340,"Would prevent operation at the minimum or maximum offset."); break; case CalibrationMinMaxError_freq: format_error_text(response,-340,"Would prevent operation at the minimum or maximum frequency."); break; case CalibrationMinMaxError_delay: format_error_text(response,-340,"Would prevent operation at the minimum or maximum delay."); break; case CalibrationMinMaxError_burst: format_error_text(response,-340,"Would prevent operation at the minimum or maximum burst separation."); break; case CalibrationMinMaxError_rise: format_error_text(response,-340,"Would prevent operation at the minimum or maximum rise time."); break; case CalibrationMinMaxError_slew: format_error_text(response,-340,"Would prevent operation at the minimum or maximum slew rate."); break; case CalibrationClosenessError: format_error_text(response,-340,"Too few calibration points, or they are too closely spaced."); break; case CalibrationRangeError: format_error_text(response,-340,"Top or bottom of range. Can not be deleted."); break; case SelfCalError: format_error_text(response,-340,"Calibration problem."); break; case HardwareError: format_error_text(response,-240,"Not possible with the current calibration settings."); break; case GPIB_missing: format_error_text(response,-240,"GPIB chip not detected. Defective hardware?"); break; case CalibrationTimingProblem: format_error_text(response,-221,"Set timing to allow operation at minimum and maximum amplitudes."); break; case Coupled_OS_Ampl_Error: format_error_text(response,-221,"If ampl > 0, ampl+offset must be > 0, if ampl < 0, ampl+offset must be < 0."); break; case PRF_limited_by_offset: format_error_text(response,-221,"Offset too high for this PRF."); break; case PW_Distort_Error: format_error_text(response,-240,"Not possible with the current PW distortion settings."); break; case DelayRangeError: format_error_text(response,-240,"Gap in possible delay values. Set delay_shrink to zero to override."); break; case ExternalModeDelayError: format_error_text(response,-240,"TRIG-OUT delay not monotonic, boost fixed delay or sync delay."); break; case burst_duty_error: format_error_text(response,-222,"Duty cycle inside burst is too high."); break; case min_burst_period_error: format_error_text(response,-222,"Time between consecutive rising edges inside burst is too low."); break; case max_burst_count_error: format_error_text(response,-222,"Too many pulses per burst."); break; case min_burst_gap_error: format_error_text(response,-222,"Pulse separation too low."); break; case max_burst_gap_error: format_error_text(response,-222,"Pulse separation too high."); break; case Burst_Exceeds_Period: format_error_text(response,-222,"Burst width can not exceed period."); break; case Dead_Time_Error: format_error_text(response,-222,"Insufficient time between end of one pulse and start of next."); break; case password_change_error: format_error_text(response,-222,"Incorrect old password, or new password is too long or short. "); break; case NetworkNotFound: format_error_text(response,-240,"Network not found."); break; case ThisShouldntHappen: format_error_text(response,-200,"Invalid execution path. Programming error."); break; case Startup_Not_Finished: format_error_text(response,-300,"Not ready for commands yet. Still booting up."); break; case obsolete_feature: format_error_text(response,-200,"Obsolete feature enabled. Re-program."); break; case config_too_large: format_error_text(response,-200,"This constant is too large. Reprogram it."); break; case config_cant_be_negative: format_error_text(response,-200,"This constant can't be negative. Reprogram it."); break; default: format_error_text(response,-200,"Specific problem unknown."); } } void check_initial_min_value (float test_limit, float *running_limit, float proposed_value, int possible_error, int *actual_error) { *running_limit = test_limit; if ( ((test_limit >= 0.0) && (proposed_value < (*running_limit * 0.999))) || ((test_limit < 0.0) && (proposed_value < (*running_limit * 1.001)))) { *actual_error = possible_error; } } void check_another_min_value (float test_limit, float *running_limit, float proposed_value, int possible_error, int *actual_error) { if (test_limit > *running_limit) { check_initial_min_value (test_limit, running_limit, proposed_value, possible_error, actual_error); } } void check_initial_max_value (float test_limit, float *running_limit, float proposed_value, int possible_error, int *actual_error) { *running_limit = test_limit; if ( ((test_limit >= 0.0) && (proposed_value > (*running_limit * 1.001))) || ((test_limit < 0.0) && (proposed_value > (*running_limit * 0.999)))) { *actual_error = possible_error; } } void check_another_max_value (float test_limit, float *running_limit, float proposed_value, int possible_error, int *actual_error) { if (test_limit < *running_limit) { check_initial_max_value (test_limit, running_limit, proposed_value, possible_error, actual_error); } } int Error_check(ChannelStruct ChannelStateToTest[max_channels]) { static GStaticMutex mutex = G_STATIC_MUTEX_INIT; g_static_mutex_lock (&mutex); 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 = OK; gboolean early_quit = FALSE; 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_pw) for (i=1; i<num_of_chan; ++i) { ChannelStateToTest[i].pw_ctrl_mode=ChannelStateToTest[0].pw_ctrl_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_inverted) for (i=1; i<num_of_chan; ++i) { ChannelStateToTest[i].inverted=ChannelStateToTest[0].inverted; } 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; } } // check for non-channel-specific obsolete features if ( globals.Flash.enable_avrq_extra_ampls ) { report_error = obsolete_feature; } for (i=0; (i<num_of_chan) && !early_quit; ++i) { /* Must be changing a setting */ globals.Timers.last_activity_at[i] = sec_timer (); /* ignore errors if it is in programming mode */ if (globals.Flash.fully_programmed != All_Programmed) { early_quit = TRUE; break; } if (globals.Flags.do_check_settings==NO) { early_quit = TRUE; break; } // check for channel-specific obsolete features if ( globals.Flash.use_high_ampl_ranges_for_high_pw_ranges[i] ) { report_error = obsolete_feature; } /* check for settings that would cause divide-by-zero errors in the error-checking routine */ if (ChannelStateToTest[i].frequency<smallest_allowed_number) { early_quit = TRUE; report_error = freq_lower_limit; break; } if (ChannelStateToTest[i].pw<smallest_allowed_number && globals.Flash.min_pw[i]>0.0) { early_quit = TRUE; report_error = pw_lower_limit; break; } if (fabs(globals.Flash.ampl_zero_equiv[i] > 2000.0)) { report_error = config_too_large; } if (fabs(globals.Flash.os_zero_equiv[i] > 2000.0)) { report_error = config_too_large; } if ( (globals.Flash.ampl_zero_equiv[i] < 0.0) || (globals.Flash.os_zero_equiv[i] < 0.0) || (globals.Flash.hvps_avg_curr_limit[i] < 0.0) || (globals.Flash.max_avg_power[i] < 0.0) ) { report_error = config_cant_be_negative; } /* 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; } /* --- check minimum frequency --- */ check_initial_min_value (globals.Flash.min_freq[i], &globals.Constraints.err_min_freq[i], ChannelStateToTest[i].frequency, freq_lower_limit, &report_error); /* ------------------------------- */ /* --- check maximum frequency --- */ check_initial_max_value (globals.Flash.max_freq[i], &globals.Constraints.err_max_freq[i], ChannelStateToTest[i].frequency, freq_upper_limit, &report_error); if ((globals.Flash.max_freq_for_high_ot[i] > 0.0) && (fabs(ChannelStateToTest[i].offset) > globals.Flash.high_ot[i])) { check_another_max_value (globals.Flash.max_freq_for_high_ot[i], &globals.Constraints.err_max_freq[i], ChannelStateToTest[i].frequency, PRF_limited_by_offset, &report_error); } check_another_max_value (0.95/fabs(ChannelStateToTest[i].delay), &globals.Constraints.err_max_freq[i], ChannelStateToTest[i].frequency, Delay_Exceeds_95Period, &report_error); if (globals.Flash.min_pw[i] > 0.0) { check_another_max_value (1/ChannelStateToTest[i].pw, &globals.Constraints.err_max_freq[i], ChannelStateToTest[i].frequency, PW_Exceeds_Period, &report_error); if ( (ChannelStateToTest[i].burst_count>1) && (globals.Flash.max_burst_count[i]>1) && !globals.Flash.burst_func[i]) { check_another_max_value (1/(ChannelStateToTest[i].burst_count * (ChannelStateToTest[i].pw+ChannelStateToTest[i].burst_time)), &globals.Constraints.err_max_freq[i], ChannelStateToTest[i].frequency, Burst_Exceeds_Period, &report_error); } check_another_max_value ((1/ChannelStateToTest[i].pw)*(ampl_fixed_max_duty/duty_scale), &globals.Constraints.err_max_freq[i], ChannelStateToTest[i].frequency, duty_cycle_upper_limit, &report_error); if (ChannelStateToTest[i].double_pulse==double_on) { // pulse sep must be less than one half-period check_another_max_value (0.5 / ChannelStateToTest[i].delay, &globals.Constraints.err_max_freq[i], ChannelStateToTest[i].frequency, Double_Separation_Too_Large, &report_error); } 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); check_another_max_value (temp, &globals.Constraints.err_max_freq[i], ChannelStateToTest[i].frequency, Average_Amplitude_Too_High, &report_error); } if ((globals.Flash.hvps_avg_curr_limit[i] > 0.0) && (fabs(ChannelStateToTest[i].amplitude) > 0.0) && (ChannelStateToTest[i].pw > 0.0)) { temp=(100.0 / duty_scale) * globals.Flash.hvps_avg_curr_limit[i] * ChannelStateToTest[i].load_type / (fabs(ChannelStateToTest[i].amplitude) * ChannelStateToTest[i].pw); check_another_max_value (temp, &globals.Constraints.err_max_freq[i], ChannelStateToTest[i].frequency, HVPS_Current_Too_High, &report_error); } 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); check_another_max_value (temp, &globals.Constraints.err_max_freq[i], ChannelStateToTest[i].frequency, average_power_limit, &report_error); } } /* ------------------------------- */ /* --- check minimum pulse width --- */ check_initial_min_value (globals.Flash.min_pw[i], &globals.Constraints.err_min_pw[i], ChannelStateToTest[i].pw, pw_lower_limit, &report_error); /* ------------------------------- */ /* --- check maximum pw ---------- */ check_initial_max_value (globals.Flash.max_pw[i], &globals.Constraints.err_max_pw[i], ChannelStateToTest[i].pw, pw_upper_limit, &report_error); /* polarity overrides */ if ((ChannelStateToTest[i].amplitude >= 0.0) && (globals.Flash.max_pw_pol[i][0] > 0.0)) { check_another_max_value (globals.Flash.max_pw_pol[i][0], &globals.Constraints.err_max_pw[i], ChannelStateToTest[i].pw, pw_upper_limit, &report_error); } else if ((ChannelStateToTest[i].amplitude <0.0) && (globals.Flash.max_pw_pol[i][1] > 0.0)) { check_another_max_value (globals.Flash.max_pw_pol[i][1], &globals.Constraints.err_max_pw[i], ChannelStateToTest[i].pw, pw_upper_limit, &report_error); } // RC limit, as per AVR-8F-B if (globals.Flash.cap_for_pw_rc_limit[i] > 0.0) { check_another_max_value (globals.Flash.cap_for_pw_rc_limit[i] * ChannelStateToTest[i].load_type, &globals.Constraints.err_max_pw[i], ChannelStateToTest[i].pw, pw_rc_limit, &report_error); } if (ChannelStateToTest[i].double_pulse==double_on) { check_another_max_value ((ChannelStateToTest[i].delay - globals.Flash.double_pulse_extra_deadtime[i]) / (1.0 + globals.Flash.double_pulse_extra_pw_margin[i]), &globals.Constraints.err_max_pw[i], ChannelStateToTest[i].pw, Double_Separation_Too_Small, &report_error); if (ChannelStateToTest[i].burst_count>1) { report_error=Cant_Do_Burst_and_Double; } } check_another_max_value ((1/ChannelStateToTest[i].frequency) - globals.Flash.dead_time[i], &globals.Constraints.err_max_pw[i], ChannelStateToTest[i].pw, Dead_Time_Error, &report_error); check_another_max_value (1/ChannelStateToTest[i].frequency, &globals.Constraints.err_max_pw[i], ChannelStateToTest[i].pw, PW_Exceeds_Period, &report_error); if ( (ChannelStateToTest[i].burst_count>1) && (globals.Flash.max_burst_count[i]>1) && !globals.Flash.burst_func[i]) { check_another_max_value ((1/ChannelStateToTest[i].frequency)/ChannelStateToTest[i].burst_count - ChannelStateToTest[i].burst_time, &globals.Constraints.err_max_pw[i], ChannelStateToTest[i].pw, Burst_Exceeds_Period, &report_error); } check_another_max_value ((1/ChannelStateToTest[i].frequency)*(ampl_fixed_max_duty/duty_scale), &globals.Constraints.err_max_pw[i], ChannelStateToTest[i].pw, duty_cycle_upper_limit, &report_error); if ((globals.Flash.max_avg_ampl[i]) > 0.0 && (fabs(ChannelStateToTest[i].amplitude)) > 0.0) { check_another_max_value (100.0 * globals.Flash.max_avg_ampl[i] / (fabs(ChannelStateToTest[i].amplitude) * ChannelStateToTest[i].frequency * duty_scale), &globals.Constraints.err_max_pw[i], ChannelStateToTest[i].pw, Average_Amplitude_Too_High, &report_error); } if ((globals.Flash.hvps_avg_curr_limit[i] > 0.0) && (fabs(ChannelStateToTest[i].amplitude) > 0.0) && (ChannelStateToTest[i].frequency > 0.0)) { check_another_max_value ((100.0 / duty_scale) * globals.Flash.hvps_avg_curr_limit[i] * ChannelStateToTest[i].load_type / (fabs(ChannelStateToTest[i].amplitude) * ChannelStateToTest[i].frequency), &globals.Constraints.err_max_pw[i], ChannelStateToTest[i].pw, HVPS_Current_Too_High, &report_error); } if (globals.Flash.max_avg_power[i] > 0.0) { check_another_max_value (globals.Flash.max_avg_power[i] * ChannelStateToTest[i].load_type / (ChannelStateToTest[i].amplitude * ChannelStateToTest[i].amplitude * ChannelStateToTest[i].frequency), &globals.Constraints.err_max_pw[i], ChannelStateToTest[i].pw, average_power_limit, &report_error); } /* ------------------------------- */ /* --- check minimum delay ------- */ if (globals.Flash.min_delay[i] != 0.0) { /* use programmed limit, if non-zero */ temp=globals.Flash.min_delay[i]; } else { /* otherwise, assume delay has equal +/- range */ temp=-globals.Flash.max_delay[i]; /* for dual-delay units, positive delay only for second channel */ if ((globals.Flash.ChanKey_delay?globals.Flash.channels:1)>1) { if (i>0) { temp=0.0; } } } check_initial_min_value (temp, &globals.Constraints.err_min_delay[i], ChannelStateToTest[i].delay, delay_lower_limit, &report_error); check_another_min_value (-0.95/ChannelStateToTest[i].frequency, &globals.Constraints.err_min_delay[i], ChannelStateToTest[i].delay, Delay_Exceeds_95Period, &report_error); if (ChannelStateToTest[i].double_pulse==double_on) { check_another_min_value (globals.Flash.double_pulse_min_sep[i], &globals.Constraints.err_min_delay[i], ChannelStateToTest[i].delay, Double_Separation_Too_Small, &report_error); check_another_min_value (ChannelStateToTest[i].pw * (1.0 + globals.Flash.double_pulse_extra_pw_margin[i]) + globals.Flash.double_pulse_extra_deadtime[i], &globals.Constraints.err_min_delay[i], ChannelStateToTest[i].delay, Double_Separation_Too_Small, &report_error); } /* ------------------------------- */ /* --- check maximum delay ------- */ check_initial_max_value (globals.Flash.max_delay[i], &globals.Constraints.err_max_delay[i], ChannelStateToTest[i].delay, delay_upper_limit, &report_error); check_another_max_value (0.95/ChannelStateToTest[i].frequency, &globals.Constraints.err_max_delay[i], ChannelStateToTest[i].delay, Delay_Exceeds_95Period, &report_error); if (ChannelStateToTest[i].double_pulse==double_on) { // one half-period check_another_max_value (0.5 / ChannelStateToTest[i].frequency, &globals.Constraints.err_max_delay[i], ChannelStateToTest[i].delay, Double_Separation_Too_Large, &report_error); } /* ------------------------------- */ // calculate duty cycle for later use duty_cycle=ChannelStateToTest[i].pw*ChannelStateToTest[i].frequency*100.0; /* calculate duty cycle */ /* disable amplitude checks if amplitude calibration is in progress */ if (!globals.Flags.extended_ampl_min_max) { /* --- check fixed amplitudes ---- */ float min_fixed_ampl, max_fixed_ampl; min_fixed_ampl = max_fixed_ampl = 0.0; gboolean uses_fixed_ampl; uses_fixed_ampl = (number_of_fixed_ampl_points(i)>0); if (uses_fixed_ampl) { get_min_max_fixed_ampls (i, &min_fixed_ampl, &max_fixed_ampl); if (!fixed_ampl_ok (i, ChannelStateToTest[i].amplitude)) { report_error=amplitude_confined_values; } } /* ------------------------------- */ /* --- check gaps in ampl range, AVRQ -AHV/-XHV ---- */ if (non_zero_first_ampl_point(i)) { if (fabs(ChannelStateToTest[i].amplitude) < globals.Flash.ampl_zero_equiv[i]) { report_error=amplitude_gap; } } /* ------------------------------------------------- */ /* --- check minimum amplitude --- */ if (uses_fixed_ampl && (min_fixed_ampl > globals.Flash.min_ampl[i])) { temp = min_fixed_ampl; } else { temp = globals.Flash.min_ampl[i]; } check_initial_min_value (temp, &globals.Constraints.err_min_ampl[i], ChannelStateToTest[i].amplitude, amplitude_lower_limit, &report_error); check_another_min_value (globals.Flash.min_vout[i]-ChannelStateToTest[i].offset, &globals.Constraints.err_min_ampl[i], ChannelStateToTest[i].amplitude, ampl_plus_os_lower_limit, &report_error); /* ------------------------------- */ /* --- check maximum amplitude --- */ if (uses_fixed_ampl && (max_fixed_ampl < globals.Flash.max_ampl[i])) { temp = max_fixed_ampl; } else { temp = globals.Flash.max_ampl[i]; } check_initial_max_value (temp, &globals.Constraints.err_max_ampl[i], ChannelStateToTest[i].amplitude, amplitude_upper_limit, &report_error); check_another_max_value (globals.Flash.max_vout[i]-ChannelStateToTest[i].offset, &globals.Constraints.err_max_ampl[i], ChannelStateToTest[i].amplitude, ampl_plus_os_upper_limit, &report_error); if (globals.Flash.max_peak_power[i] > 0.0) { temp = sqrt(globals.Flash.max_peak_power[i] * ChannelStateToTest[i].load_type); // temp is positive at this point check_another_max_value (temp, &globals.Constraints.err_max_ampl[i], ChannelStateToTest[i].amplitude, peak_power_limit, &report_error); temp = temp * -1.0; // check negative possibility check_another_min_value (temp, &globals.Constraints.err_min_ampl[i], ChannelStateToTest[i].amplitude, peak_power_limit, &report_error); } if (globals.Flash.max_avg_power[i] > 0.0) { temp = sqrt(globals.Flash.max_avg_power[i] * ChannelStateToTest[i].load_type / (ChannelStateToTest[i].pw * ChannelStateToTest[i].frequency)); // temp is positive at this point check_another_max_value (temp, &globals.Constraints.err_max_ampl[i], ChannelStateToTest[i].amplitude, average_power_limit, &report_error); temp = temp * -1.0; // check negative possibility check_another_min_value (temp, &globals.Constraints.err_min_ampl[i], ChannelStateToTest[i].amplitude, average_power_limit, &report_error); } if (globals.Flash.min_pw[i] > 0.0) { /* Check average amplitude */ if (globals.Flash.max_avg_ampl[i] > 0.0) { temp = 100.0 * globals.Flash.max_avg_ampl[i] / (ChannelStateToTest[i].frequency * ChannelStateToTest[i].pw * duty_scale); // temp is positive at this point check_another_max_value (temp, &globals.Constraints.err_max_ampl[i], ChannelStateToTest[i].amplitude, Average_Amplitude_Too_High, &report_error); temp = temp * -1.0; // check negative possibility check_another_min_value (temp, &globals.Constraints.err_min_ampl[i], ChannelStateToTest[i].amplitude, Average_Amplitude_Too_High, &report_error); } if ((globals.Flash.hvps_avg_curr_limit[i] > 0.0) && (fabs(ChannelStateToTest[i].frequency) > 0.0) && (ChannelStateToTest[i].pw > 0.0)) { temp=(100.0 / duty_scale) * globals.Flash.hvps_avg_curr_limit[i] * ChannelStateToTest[i].load_type / (ChannelStateToTest[i].frequency * ChannelStateToTest[i].pw); // temp is positive at this point check_another_max_value (temp, &globals.Constraints.err_max_ampl[i], ChannelStateToTest[i].amplitude, HVPS_Current_Too_High, &report_error); temp = temp * -1.0; // check negative possibility if (temp > globals.Constraints.err_min_ampl[i]) { globals.Constraints.err_min_ampl[i]=temp; if (ChannelStateToTest[i].amplitude<(1.001*globals.Constraints.err_min_ampl[i])) { report_error=HVPS_Current_Too_High; } } } if (duty_cycle>(100.0*ampl_fixed_max_duty/duty_scale)) /* set at crossover voltage */ { // FIXME to use check_ functions 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 ------ */ check_initial_min_value (globals.Flash.min_offset[i], &globals.Constraints.err_min_offset[i], ChannelStateToTest[i].offset, offset_lower_limit, &report_error); check_another_min_value (globals.Flash.min_vout[i]-ChannelStateToTest[i].amplitude, &globals.Constraints.err_min_offset[i], ChannelStateToTest[i].offset, ampl_plus_os_lower_limit, &report_error); /* 1011 models: high level of PG-P output must remain positive */ // FIXME use new check_ functions? 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; } } } } if ( (globals.Flash.max_freq_for_high_ot[i] > 0.0) && (ChannelStateToTest[i].frequency > globals.Flash.max_freq_for_high_ot[i])) { temp = -globals.Flash.high_ot[i]; 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=PRF_limited_by_offset; } } } /* ------------------------------- */ /* --- check maximum offset ------ */ check_initial_max_value (globals.Flash.max_offset[i], &globals.Constraints.err_max_offset[i], ChannelStateToTest[i].offset, offset_upper_limit, &report_error); check_another_max_value (globals.Flash.max_vout[i]-ChannelStateToTest[i].amplitude, &globals.Constraints.err_max_offset[i], ChannelStateToTest[i].offset, ampl_plus_os_upper_limit, &report_error); /* 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; } } } } if ( (globals.Flash.max_freq_for_high_ot[i] > 0.0) && (ChannelStateToTest[i].frequency > globals.Flash.max_freq_for_high_ot[i])) { temp = globals.Flash.high_ot[i]; 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=PRF_limited_by_offset; } } } /* ------------------------------- */ } } /* --- 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 --- */ // FIXME - update with new check_ routines, but only report error if count>1 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 --- */ // FIXME - update with new check_ routines, but only report error if count>1 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 --- */ // FIXME - update with new check_ routines, but only report error if count>1 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.Flags.extended_ampl_min_max) { if (globals.Flash.rise_time_min_max_only[i]) { if ( !(fabs(ChannelStateToTest[i].rise_time - globals.Flash.min_rise_time[i]) < smallest_allowed_number ) && !(fabs(ChannelStateToTest[i].rise_time - globals.Flash.max_rise_time[i]) < smallest_allowed_number ) ) { report_error=rise_time_confined_values; } } check_initial_min_value (globals.Flash.min_rise_time[i], &globals.Constraints.err_min_rise_time[i], ChannelStateToTest[i].rise_time, min_rise_time_error, &report_error); check_initial_max_value (globals.Flash.max_rise_time[i], &globals.Constraints.err_max_rise_time[i], ChannelStateToTest[i].rise_time, max_rise_time_error, &report_error); } /* --- check slew settings --- */ /* disable amplitude checks if calibration is in progress */ if (globals.Flash.curr_slew[i]) if (!globals.Flags.extended_ampl_min_max) { check_initial_min_value (globals.Flash.min_slew[i], &globals.Constraints.err_min_slew[i], ChannelStateToTest[i].slew, min_slew_error, &report_error); check_initial_max_value (globals.Flash.max_slew[i], &globals.Constraints.err_max_slew[i], ChannelStateToTest[i].slew, max_slew_error, &report_error); } /* --- check resistance settings --- */ if (globals.Flash.switchable_load[i]) { check_initial_min_value (globals.Flash.low_load_type[i], &globals.Constraints.err_min_load_type[i], ChannelStateToTest[i].load_type, min_load_type_error, &report_error); if (duty_cycle > max_duty_this_ampl) { check_another_min_value (globals.Flash.low_load_type[i] * duty_cycle / max_duty_this_ampl, &globals.Constraints.err_min_load_type[i], ChannelStateToTest[i].load_type, min_load_type_error, &report_error); } } if (globals.Flash.cap_for_pw_rc_limit[i] > 0.0) { check_another_min_value (ChannelStateToTest[i].pw / globals.Flash.cap_for_pw_rc_limit[i], &globals.Constraints.err_min_load_type[i], ChannelStateToTest[i].load_type, pw_rc_limit, &report_error); } if (globals.Flash.hvps_avg_curr_limit[i] > 0.0) { check_another_min_value ((duty_scale / 100.0) * fabs(ChannelStateToTest[i].amplitude) * ChannelStateToTest[i].pw * ChannelStateToTest[i].frequency / globals.Flash.hvps_avg_curr_limit[i], &globals.Constraints.err_min_load_type[i], ChannelStateToTest[i].load_type, HVPS_Current_Too_High, &report_error); } if (globals.Flash.max_peak_power[i] > 0.0) { check_another_min_value (ChannelStateToTest[i].amplitude * ChannelStateToTest[i].amplitude / globals.Flash.max_peak_power[i], &globals.Constraints.err_min_load_type[i], ChannelStateToTest[i].load_type, peak_power_limit, &report_error); } if (globals.Flash.max_avg_power[i] > 0.0) { check_another_min_value ((ChannelStateToTest[i].amplitude * ChannelStateToTest[i].amplitude * ChannelStateToTest[i].pw * ChannelStateToTest[i].frequency) / globals.Flash.max_avg_power[i], &globals.Constraints.err_min_load_type[i], ChannelStateToTest[i].load_type, average_power_limit, &report_error); } check_initial_max_value (globals.Flash.high_load_type[i], &globals.Constraints.err_max_load_type[i], ChannelStateToTest[i].load_type, max_load_type_error, &report_error); /* --- check soft_current_limit settings --- */ if (globals.Flash.soft_current_limit_enabled[i]) { // FIXME to use new check_ functions 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 ---- */ } // merge min/max values for shared channel variables on multi-channel instruments // for example, ampl on CH2 may force lower max freq on all channels if (num_of_chan>1) { if (!globals.Flash.ChanKey_frequency) for (i=1; i<num_of_chan; ++i) { if (globals.Constraints.err_min_freq[0] < globals.Constraints.err_min_freq[i]) { globals.Constraints.err_min_freq[0] = globals.Constraints.err_min_freq[i]; } if (globals.Constraints.err_max_freq[0] > globals.Constraints.err_max_freq[i]) { globals.Constraints.err_max_freq[0] = globals.Constraints.err_max_freq[i]; } } if (!globals.Flash.ChanKey_delay) for (i=1; i<num_of_chan; ++i) { if (globals.Constraints.err_min_delay[0] < globals.Constraints.err_min_delay[i]) { globals.Constraints.err_min_delay[0] = globals.Constraints.err_min_delay[i]; } if (globals.Constraints.err_max_delay[0] > globals.Constraints.err_max_delay[i]) { globals.Constraints.err_max_delay[0] = globals.Constraints.err_max_delay[i]; } } if (!globals.Flash.ChanKey_pw) for (i=1; i<num_of_chan; ++i) { if (globals.Constraints.err_min_pw[0] < globals.Constraints.err_min_pw[i]) { globals.Constraints.err_min_pw[0] = globals.Constraints.err_min_pw[i]; } if (globals.Constraints.err_max_pw[0] > globals.Constraints.err_max_pw[i]) { globals.Constraints.err_max_pw[0] = globals.Constraints.err_max_pw[i]; } } if (!globals.Flash.ChanKey_amplitude) for (i=1; i<num_of_chan; ++i) { if (globals.Constraints.err_min_ampl[0] < globals.Constraints.err_min_ampl[i]) { globals.Constraints.err_min_ampl[0] = globals.Constraints.err_min_ampl[i]; } if (globals.Constraints.err_max_ampl[0] > globals.Constraints.err_max_ampl[i]) { globals.Constraints.err_max_ampl[0] = globals.Constraints.err_max_ampl[i]; } } if (!globals.Flash.ChanKey_offset) for (i=1; i<num_of_chan; ++i) { if (globals.Constraints.err_min_offset[0] < globals.Constraints.err_min_offset[i]) { globals.Constraints.err_min_offset[0] = globals.Constraints.err_min_offset[i]; } if (globals.Constraints.err_max_offset[0] > globals.Constraints.err_max_offset[i]) { globals.Constraints.err_max_offset[0] = globals.Constraints.err_max_offset[i]; } } if (!globals.Flash.ChanKey_load_type) for (i=1; i<num_of_chan; ++i) { if (globals.Constraints.err_min_load_type[0] < globals.Constraints.err_min_load_type[i]) { globals.Constraints.err_min_load_type[0] = globals.Constraints.err_min_load_type[i]; } if (globals.Constraints.err_max_load_type[0] > globals.Constraints.err_max_load_type[i]) { globals.Constraints.err_max_load_type[0] = globals.Constraints.err_max_load_type[i]; } } if (!globals.Flash.ChanKey_Burst_Count) for (i=1; i<num_of_chan; ++i) { if (globals.Constraints.err_max_burst_count[0] > globals.Constraints.err_max_burst_count[i]) { globals.Constraints.err_max_burst_count[0] = globals.Constraints.err_max_burst_count[i]; } } if (!globals.Flash.ChanKey_Burst_Time) for (i=1; i<num_of_chan; ++i) { if (globals.Constraints.err_min_burst_time[0] < globals.Constraints.err_min_burst_time[i]) { globals.Constraints.err_min_burst_time[0] = globals.Constraints.err_min_burst_time[i]; } if (globals.Constraints.err_max_burst_time[0] > globals.Constraints.err_max_burst_time[i]) { globals.Constraints.err_max_burst_time[0] = globals.Constraints.err_max_burst_time[i]; } } if (!globals.Flash.ChanKey_rise_time) for (i=1; i<num_of_chan; ++i) { if (globals.Constraints.err_min_rise_time[0] < globals.Constraints.err_min_rise_time[i]) { globals.Constraints.err_min_rise_time[0] = globals.Constraints.err_min_rise_time[i]; } if (globals.Constraints.err_max_rise_time[0] > globals.Constraints.err_max_rise_time[i]) { globals.Constraints.err_max_rise_time[0] = globals.Constraints.err_max_rise_time[i]; } } if (!globals.Flash.ChanKey_slew) for (i=1; i<num_of_chan; ++i) { if (globals.Constraints.err_min_slew[0] < globals.Constraints.err_min_slew[i]) { globals.Constraints.err_min_slew[0] = globals.Constraints.err_min_slew[i]; } if (globals.Constraints.err_max_slew[0] > globals.Constraints.err_max_slew[i]) { globals.Constraints.err_max_slew[0] = globals.Constraints.err_max_slew[i]; } } if (!globals.Flash.ChanKey_current_limit) for (i=1; i<num_of_chan; ++i) { if (globals.Constraints.err_min_soft_current_limit[0] < globals.Constraints.err_min_soft_current_limit[i]) { globals.Constraints.err_min_soft_current_limit[0] = globals.Constraints.err_min_soft_current_limit[i]; } if (globals.Constraints.err_max_soft_current_limit[0] > globals.Constraints.err_max_soft_current_limit[i]) { globals.Constraints.err_max_soft_current_limit[0] = globals.Constraints.err_max_soft_current_limit[i]; } } } g_static_mutex_unlock (&mutex); return report_error; }