/* 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 #include #include #include #include "globals.h" #include "lcd.h" #include "error_utils.h" #include "menus.h" #include "gpib.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: 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: case CalibrationClosenessError: case CalibrationRangeError: case CalibrationPolarityError: case Soft_Limit_Exceeded: case SelfCalError: case NetworkNotFound: case Startup_Not_Finished: 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 ", response); send_message(broadcast_str); g_free (broadcast_str); g_free (response); } /*----------------------------------------------------------------------------------------------------------*/ void Error_Remove_From_Queue(void) { int i; for (i=1; i 0, ampl+offset must be > 0, if ampl < 0, ampl+offset must be < 0."); break; case PW_Distort_Error: format_error_text(response,-240,"Not possible with the current PW distortion settings."); 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 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; default: format_error_text(response,-200,"Specific problem unknown."); } } 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; i0.0) { early_quit = TRUE; report_error = pw_lower_limit; break; } /* calculate maximum duty cycle based on amplitude and load, for later use */ max_duty_high_ampl=globals.Flash.max_duty_high[i]; max_duty_low_ampl=globals.Flash.max_duty_low[i]; /* Choose highest of 4 duty cycles that meet max ampl limits */ if (globals.Flash.duty_ampl[i]>0.0 && (fabs(ChannelStateToTest[i].amplitude)<= globals.Flash.duty_ampl[i])) { max_duty_this_ampl=max_duty_low_ampl; } else { max_duty_this_ampl=max_duty_high_ampl; } if (globals.Flash.duty_ampl_mid1[i]>0.0 && (fabs(ChannelStateToTest[i].amplitude)<= globals.Flash.duty_ampl_mid1[i]) && (globals.Flash.max_duty_mid1[i] > max_duty_this_ampl)) { max_duty_this_ampl = globals.Flash.max_duty_mid1[i]; } if (globals.Flash.duty_ampl_mid2[i]>0.0 && (fabs(ChannelStateToTest[i].amplitude)<= globals.Flash.duty_ampl_mid2[i]) && (globals.Flash.max_duty_mid2[i] > max_duty_this_ampl)) { max_duty_this_ampl = globals.Flash.max_duty_mid2[i]; } ampl_fixed_max_duty = max_duty_this_ampl; if (globals.Flash.switchable_load[i]) { ampl_fixed_max_duty = max_duty_this_ampl * (ChannelStateToTest[i].load_type / globals.Flash.low_load_type[i]); temp = globals.Flash.max_high_rl_duty[i]; if (ampl_fixed_max_duty > temp) { ampl_fixed_max_duty = temp; } } /* take burst mode and double-pulse mode into account when setting the maximum duty cycle */ duty_scale = 100.0; /* convert from percent */ if (ChannelStateToTest[i].double_pulse==double_on) { duty_scale = 200.0; } if ( (ChannelStateToTest[i].burst_count>1) && (globals.Flash.max_burst_count[i]>1) && !globals.Flash.burst_func[i]) { duty_scale *= (float) ChannelStateToTest[i].burst_count; } if (ChannelStateToTest[i].trigger_source==source_internal) { /* --- check minimum frequency --- */ globals.Constraints.err_min_freq[i]=globals.Flash.min_freq[i]; if (ChannelStateToTest[i].frequency<(0.999*globals.Constraints.err_min_freq[i])) { report_error=freq_lower_limit; } if ((ChannelStateToTest[i].polarity!=pol_norm) && (globals.Flash.min_pw[i]>0.0)) { temp=(1/ChannelStateToTest[i].pw)*( 1.0- ampl_fixed_max_duty/duty_scale ); if (temp>globals.Constraints.err_min_freq[i]) { globals.Constraints.err_min_freq[i]=temp; if (ChannelStateToTest[i].frequency<(0.999*globals.Constraints.err_min_freq[i])) { report_error=duty_cycle_upper_limit; } } } /* ------------------------------- */ /* --- check maximum frequency --- */ globals.Constraints.err_max_freq[i]=globals.Flash.max_freq[i]; if (ChannelStateToTest[i].frequency>(1.001*globals.Constraints.err_max_freq[i])) { report_error=freq_upper_limit; } if (fabs(ChannelStateToTest[i].delay)>1.0e-15) { temp=0.95/fabs(ChannelStateToTest[i].delay); if (temp(1.001*globals.Constraints.err_max_freq[i])) { report_error=Delay_Exceeds_95Period; } } } if (globals.Flash.min_pw[i] > 0.0) { temp=1/ChannelStateToTest[i].pw; if (temp(1.001*globals.Constraints.err_max_freq[i])) { report_error=PW_Exceeds_Period; } } if ( (ChannelStateToTest[i].burst_count>1) && (globals.Flash.max_burst_count[i]>1) && !globals.Flash.burst_func[i]) { temp=1/(ChannelStateToTest[i].burst_count * (ChannelStateToTest[i].pw+ChannelStateToTest[i].burst_time)); if (temp(1.001*globals.Constraints.err_max_freq[i])) { report_error=Burst_Exceeds_Period; } } } if (ChannelStateToTest[i].polarity==pol_norm) { temp=(1/ChannelStateToTest[i].pw)*(ampl_fixed_max_duty/duty_scale); if (temp(1.001*globals.Constraints.err_max_freq[i])) { report_error=duty_cycle_upper_limit; } } } if (ChannelStateToTest[i].double_pulse==double_on) { temp=0.95/(ChannelStateToTest[i].pw+fabs(ChannelStateToTest[i].delay)); if (temp(1.001*globals.Constraints.err_max_freq[i])) { report_error=Double_Separation_Too_Large; } } } if ((globals.Flash.max_avg_ampl[i]) > 0.0 && (fabs(ChannelStateToTest[i].amplitude)) > 0.0) { temp=100.0 * globals.Flash.max_avg_ampl[i] / (fabs(ChannelStateToTest[i].amplitude) * ChannelStateToTest[i].pw * duty_scale); if (temp(1.001*globals.Constraints.err_max_freq[i])) { report_error=Average_Amplitude_Too_High; } } } if (globals.Flash.max_avg_power[i] > 0.0) { temp = (globals.Flash.max_avg_power[i] * ChannelStateToTest[i].load_type) / (ChannelStateToTest[i].amplitude * ChannelStateToTest[i].amplitude * ChannelStateToTest[i].pw); if (temp < globals.Constraints.err_max_freq[i]) { globals.Constraints.err_max_freq[i] = temp; if (ChannelStateToTest[i].frequency>(1.001*globals.Constraints.err_max_freq[i])) { report_error=average_power_limit; } } } } /* ------------------------------- */ } /* --- check minimum pulse width --- */ globals.Constraints.err_min_pw[i]=globals.Flash.min_pw[i]; if ( (globals.Constraints.err_min_pw[i]>=0.0 && ChannelStateToTest[i].pw<(0.999*globals.Constraints.err_min_pw[i])) || (globals.Constraints.err_min_pw[i]<0.0 && ChannelStateToTest[i].pw<(1.001*globals.Constraints.err_min_pw[i])) ) { report_error=pw_lower_limit; } /* negative-pw units are special, ignore PRF / duty cycle / PW conflicts */ if (globals.Constraints.err_min_pw[i]>=0.0) { if (ChannelStateToTest[i].trigger_source==source_internal) { if (ChannelStateToTest[i].polarity!=pol_norm) { temp=(1/ChannelStateToTest[i].frequency)*( 1.0 - ampl_fixed_max_duty/duty_scale ); if (temp>globals.Constraints.err_min_pw[i]) { globals.Constraints.err_min_pw[i]=temp; if (ChannelStateToTest[i].pw<(0.999*globals.Constraints.err_min_pw[i])) { report_error=duty_cycle_upper_limit; } } } } } /* ------------------------------- */ /* --- check maximum pw ---------- */ globals.Constraints.err_max_pw[i]=globals.Flash.max_pw[i]; /* polarity overrides */ if ((ChannelStateToTest[i].amplitude >= 0.0) && (globals.Flash.max_pw_pol[i][0] > 0.0) && (globals.Constraints.err_max_pw[i] > globals.Flash.max_pw_pol[i][0])) { globals.Constraints.err_max_pw[i] = globals.Flash.max_pw_pol[i][0]; } else if ((ChannelStateToTest[i].amplitude <0.0) && (globals.Flash.max_pw_pol[i][1] > 0.0) && (globals.Constraints.err_max_pw[i] > globals.Flash.max_pw_pol[i][1])) { globals.Constraints.err_max_pw[i] = globals.Flash.max_pw_pol[i][1]; } if (ChannelStateToTest[i].pw>(1.001*globals.Constraints.err_max_pw[i])) { report_error=pw_upper_limit; } if (ChannelStateToTest[i].double_pulse==double_on) { temp=ChannelStateToTest[i].delay; if (temp(1.001*globals.Constraints.err_max_pw[i])) { report_error=PW_Exceeds_Double_Separation; } } } if (ChannelStateToTest[i].trigger_source==source_internal) { temp=1/ChannelStateToTest[i].frequency; if (temp(1.001*globals.Constraints.err_max_pw[i])) { report_error=PW_Exceeds_Period; } } if ( (ChannelStateToTest[i].burst_count>1) && (globals.Flash.max_burst_count[i]>1) && !globals.Flash.burst_func[i]) { temp=(1/ChannelStateToTest[i].frequency)/ChannelStateToTest[i].burst_count - ChannelStateToTest[i].burst_time; if (temp(1.001*globals.Constraints.err_max_pw[i])) { report_error=Burst_Exceeds_Period; } } } if (ChannelStateToTest[i].polarity==pol_norm) { temp=(1/ChannelStateToTest[i].frequency)*(ampl_fixed_max_duty/duty_scale); if (temp(1.001*globals.Constraints.err_max_pw[i])) { report_error=duty_cycle_upper_limit; } } } if (ChannelStateToTest[i].double_pulse==double_on) { temp=(0.95/ChannelStateToTest[i].frequency)-ChannelStateToTest[i].delay; if (temp(1.001*globals.Constraints.err_max_pw[i])) { report_error=Double_Separation_Too_Large; } } } if ((globals.Flash.max_avg_ampl[i]) > 0.0 && (fabs(ChannelStateToTest[i].amplitude)) > 0.0) { temp=100.0 * globals.Flash.max_avg_ampl[i] / (fabs(ChannelStateToTest[i].amplitude) * ChannelStateToTest[i].frequency * duty_scale); if (temp(1.001*globals.Constraints.err_max_pw[i])) { report_error=Average_Amplitude_Too_High; } } } if (globals.Flash.max_avg_power[i] > 0.0) { temp = globals.Flash.max_avg_power[i] * ChannelStateToTest[i].load_type / (ChannelStateToTest[i].amplitude * ChannelStateToTest[i].amplitude * ChannelStateToTest[i].frequency); if (temp < globals.Constraints.err_max_pw[i]) { globals.Constraints.err_max_pw[i] = temp; if (ChannelStateToTest[i].pw>(1.001*globals.Constraints.err_max_pw[i])) { report_error=average_power_limit; } } } } /* ------------------------------- */ /* --- check minimum delay ------- */ if (globals.Flash.min_delay[i] != 0.0) { /* use programmed limit, if non-zero */ globals.Constraints.err_min_delay[i]=globals.Flash.min_delay[i]; } else { /* otherwise, assume delay has equal +/- range */ globals.Constraints.err_min_delay[i]=-globals.Flash.max_delay[i]; /* for dual-delay units, positive delay only */ if ((globals.Flash.ChanKey_delay?globals.Flash.channels:1)>1) { globals.Constraints.err_min_delay[i]=0.0; } } if ( (globals.Constraints.err_min_delay[i]>=0.0 && ChannelStateToTest[i].delay<(0.999*globals.Constraints.err_min_delay[i])) || (globals.Constraints.err_min_delay[i]<0.0 && ChannelStateToTest[i].delay<(1.001*globals.Constraints.err_min_delay[i])) ) { report_error=delay_lower_limit; } if (ChannelStateToTest[i].trigger_source==source_internal) { temp=-0.95/ChannelStateToTest[i].frequency; if (temp>globals.Constraints.err_min_delay[i]) { globals.Constraints.err_min_delay[i]=temp; if ( (globals.Constraints.err_min_delay[i]>=0.0 && ChannelStateToTest[i].delay<(0.999*globals.Constraints.err_min_delay[i])) || (globals.Constraints.err_min_delay[i]<0.0 && ChannelStateToTest[i].delay<(1.001*globals.Constraints.err_min_delay[i])) ) { report_error=Delay_Exceeds_95Period; } } } if (ChannelStateToTest[i].double_pulse==double_on) { temp=ChannelStateToTest[i].pw; if (temp>globals.Constraints.err_min_delay[i]) { globals.Constraints.err_min_delay[i]=temp; if ( (globals.Constraints.err_min_delay[i]>=0.0 && ChannelStateToTest[i].delay<(0.999*globals.Constraints.err_min_delay[i])) || (globals.Constraints.err_min_delay[i]<0.0 && ChannelStateToTest[i].delay<(1.001*globals.Constraints.err_min_delay[i])) ) { report_error=PW_Exceeds_Double_Separation; } } } /* ------------------------------- */ /* --- check maximum delay ------- */ globals.Constraints.err_max_delay[i]=globals.Flash.max_delay[i]; if ( (globals.Constraints.err_max_delay[i]>=0.0 && ChannelStateToTest[i].delay>(1.001*globals.Constraints.err_max_delay[i])) || (globals.Constraints.err_max_delay[i]<0.0 && ChannelStateToTest[i].delay>(0.999*globals.Constraints.err_max_delay[i])) ) { report_error=delay_upper_limit; } if (ChannelStateToTest[i].trigger_source==source_internal) { temp=0.95/ChannelStateToTest[i].frequency; if (temp=0.0 && ChannelStateToTest[i].delay>(1.001*globals.Constraints.err_max_delay[i])) || (globals.Constraints.err_max_delay[i]<0.0 && ChannelStateToTest[i].delay>(0.999*globals.Constraints.err_max_delay[i])) ) { report_error=Delay_Exceeds_95Period; } } if (ChannelStateToTest[i].double_pulse==double_on) { temp=(0.95/ChannelStateToTest[i].frequency)-ChannelStateToTest[i].pw; if (temp=0.0 && ChannelStateToTest[i].delay>(1.001*globals.Constraints.err_max_delay[i])) || (globals.Constraints.err_max_delay[i]<0.0 && ChannelStateToTest[i].delay>(0.999*globals.Constraints.err_max_delay[i])) ) { report_error=Double_Separation_Too_Large; } } } } /* ------------------------------- */ /* disable amplitude checks if amplitude calibration is in progress */ if (!globals.Flags.extended_ampl_min_max) { globals.Constraints.err_max_vcc1[i]=globals.Flash.vcc1_max[i]; globals.Constraints.err_max_vcc2[i]=globals.Flash.vcc2_max[i]; globals.Constraints.err_max_vlogic[i]=ChannelStateToTest[0].vcc1; globals.Constraints.err_min_vcc1[i]=0.0; globals.Constraints.err_min_vcc2[i]=globals.Flash.vcc2_min[i]; globals.Constraints.err_min_vlogic[i]=0.0; if ( ChannelStateToTest[i].vcc1>(1.001*globals.Constraints.err_max_vcc1[i])) { report_error=amplitude_upper_limit; } if ( ChannelStateToTest[i].vcc2>(1.001*globals.Constraints.err_max_vcc2[i])) { report_error=amplitude_upper_limit; } if ( ChannelStateToTest[i].vlogic>(1.001*globals.Constraints.err_max_vlogic[i])) { report_error=amplitude_upper_limit; } if ( ChannelStateToTest[i].vcc1=0.0 && ChannelStateToTest[i].amplitude<(0.999*globals.Constraints.err_min_ampl[i])) || (globals.Constraints.err_min_ampl[i]<0.0 && ChannelStateToTest[i].amplitude<(1.001*globals.Constraints.err_min_ampl[i])) ) { report_error=amplitude_lower_limit; } temp=globals.Flash.min_vout[i]-ChannelStateToTest[i].offset; if (temp>globals.Constraints.err_min_ampl[i]) { globals.Constraints.err_min_ampl[i]=temp; if ( (globals.Constraints.err_min_ampl[i]>=0.0 && ChannelStateToTest[i].amplitude<(0.999*globals.Constraints.err_min_ampl[i])) || (globals.Constraints.err_min_ampl[i]<0.0 && ChannelStateToTest[i].amplitude<(1.001*globals.Constraints.err_min_ampl[i])) ) { report_error=ampl_plus_os_lower_limit; } } /* ------------------------------- */ /* --- check intermediate amplitude --- */ if (globals.Flash.ampl_min_max_only[i]) if ( !(fabs(ChannelStateToTest[i].amplitude - globals.Flash.min_ampl[i] ) < globals.Flash.ampl_zero_equiv[i] ) && !(fabs(ChannelStateToTest[i].amplitude - globals.Flash.max_ampl[i]) < globals.Flash.ampl_zero_equiv[i] ) ) { report_error=amplitude_confined_values; } /* ------------------------------- */ /* --- check maximum amplitude --- */ globals.Constraints.err_max_ampl[i]=globals.Flash.max_ampl[i]; if ( (globals.Constraints.err_max_ampl[i]>=0.0 && ChannelStateToTest[i].amplitude>(1.001*globals.Constraints.err_max_ampl[i])) || (globals.Constraints.err_max_ampl[i]<0.0 && ChannelStateToTest[i].amplitude>(0.999*globals.Constraints.err_max_ampl[i])) ) { report_error=amplitude_upper_limit; } temp = sqrt(globals.Flash.max_peak_power[i] * ChannelStateToTest[i].load_type); if ((temp > 0.0) && (temp < globals.Constraints.err_max_ampl[i])) { globals.Constraints.err_max_ampl[i] = temp; if (-temp > globals.Constraints.err_min_ampl[i]) { globals.Constraints.err_min_ampl[i] = -temp; } if ((1.001*globals.Constraints.err_max_ampl[i]) < fabs(ChannelStateToTest[i].amplitude)) { report_error=peak_power_limit; } } if (ChannelStateToTest[i].trigger_source==source_internal) { temp = sqrt(globals.Flash.max_avg_power[i] * ChannelStateToTest[i].load_type / (ChannelStateToTest[i].pw * ChannelStateToTest[i].frequency)); if ((temp > 0.0) && (temp < globals.Constraints.err_max_ampl[i])) { globals.Constraints.err_max_ampl[i] = temp; if (-temp > globals.Constraints.err_min_ampl[i]) { globals.Constraints.err_min_ampl[i] = -temp; } if ((1.001*globals.Constraints.err_max_ampl[i]) < fabs(ChannelStateToTest[i].amplitude)) { report_error=average_power_limit; } } } temp=globals.Flash.max_vout[i]-ChannelStateToTest[i].offset; if (temp=0.0 && ChannelStateToTest[i].amplitude>(1.001*globals.Constraints.err_max_ampl[i])) || (globals.Constraints.err_max_ampl[i]<0.0 && ChannelStateToTest[i].amplitude>(0.999*globals.Constraints.err_max_ampl[i])) ) { report_error=ampl_plus_os_upper_limit; } } if (globals.Flash.min_pw[i] > 0.0) { /* Check average amplitude */ if ((globals.Flash.max_avg_ampl[i]) > 0.0 && (fabs(ChannelStateToTest[i].amplitude)) > 0.0) { temp=100.0 * globals.Flash.max_avg_ampl[i] / (ChannelStateToTest[i].frequency * ChannelStateToTest[i].pw * duty_scale); if (temp=0.0 && ChannelStateToTest[i].amplitude>(1.001*globals.Constraints.err_max_ampl[i])) || (globals.Constraints.err_max_ampl[i]<0.0 && ChannelStateToTest[i].amplitude>(0.999*globals.Constraints.err_max_ampl[i])) ) { report_error=Average_Amplitude_Too_High; } } } duty_cycle=ChannelStateToTest[i].pw*ChannelStateToTest[i].frequency*100; /* calculate duty cycle */ if (ChannelStateToTest[i].polarity!=pol_norm) { duty_cycle=100-duty_cycle; /* account for inversion */ } if (duty_cycle>(100.0*ampl_fixed_max_duty/duty_scale)) /* set at crossover voltage */ { temp=globals.Flash.duty_ampl[i]; if (temp=0.0 && ChannelStateToTest[i].amplitude>(1.001*globals.Constraints.err_max_ampl[i])) || (globals.Constraints.err_max_ampl[i]<0.0 && ChannelStateToTest[i].amplitude>(0.999*globals.Constraints.err_max_ampl[i])) ) && (duty_cycle > 1.001*(100.0*max_duty_high_ampl/duty_scale)) ) { report_error=duty_cycle_upper_limit; } } } } /* ------------------------------- */ if ((globals.Flash.voltage_offset_enabled[i]) || (globals.Flash.current_offset_enabled[i])) { /* --- check minimum offset ------ */ globals.Constraints.err_min_offset[i]=globals.Flash.min_offset[i]; if ( (globals.Constraints.err_min_offset[i]>=0.0 && ChannelStateToTest[i].offset<(0.999*globals.Constraints.err_min_offset[i])) || (globals.Constraints.err_min_offset[i]<0.0 && ChannelStateToTest[i].offset<(1.001*globals.Constraints.err_min_offset[i])) ) { report_error=offset_lower_limit; } temp=globals.Flash.min_vout[i]-ChannelStateToTest[i].amplitude; if (temp>globals.Constraints.err_min_offset[i]) { globals.Constraints.err_min_offset[i]=temp; if ( (globals.Constraints.err_min_offset[i]>=0.0 && ChannelStateToTest[i].offset<(0.999*globals.Constraints.err_min_offset[i])) || (globals.Constraints.err_min_offset[i]<0.0 && ChannelStateToTest[i].offset<(1.001*globals.Constraints.err_min_offset[i])) ) { report_error=ampl_plus_os_lower_limit; } } /* 1011 models: high level of PG-P output must remain positive */ if (globals.Flash.ampl_coupled_to_os[i]) { if (ChannelStateToTest[i].amplitude>globals.Flash.ampl_zero_equiv[i]) { temp=-ChannelStateToTest[i].amplitude; if (temp>globals.Constraints.err_min_offset[i]) { globals.Constraints.err_min_offset[i]=temp; if (ChannelStateToTest[i].offset<=globals.Constraints.err_min_offset[i]) { report_error=Coupled_OS_Ampl_Error; } } } } /* ------------------------------- */ /* --- check maximum offset ------ */ globals.Constraints.err_max_offset[i]=globals.Flash.max_offset[i]; if ( (globals.Constraints.err_max_offset[i]>=0.0 && ChannelStateToTest[i].offset>(1.001*globals.Constraints.err_max_offset[i])) || (globals.Constraints.err_max_offset[i]<0.0 && ChannelStateToTest[i].offset>(0.999*globals.Constraints.err_max_offset[i])) ) { report_error=offset_upper_limit; } temp=globals.Flash.max_vout[i]-ChannelStateToTest[i].amplitude; if (temp=0.0 && ChannelStateToTest[i].offset>(1.001*globals.Constraints.err_max_offset[i])) || (globals.Constraints.err_max_offset[i]<0.0 && ChannelStateToTest[i].offset>(0.999*globals.Constraints.err_max_offset[i])) ) { report_error=ampl_plus_os_upper_limit; } } /* 1011 models: low level of PG-N output must remain negative */ if (globals.Flash.ampl_coupled_to_os[i]) { if (ChannelStateToTest[i].amplitude<-globals.Flash.ampl_zero_equiv[i]) { temp=-ChannelStateToTest[i].amplitude; if (temp=globals.Constraints.err_max_offset[i]) { report_error=Coupled_OS_Ampl_Error; } } } } /* ------------------------------- */ } } /* --- check for nonsensical negatives ------ */ if ( ChannelStateToTest[i].frequency<0.0 || ((ChannelStateToTest[i].pw<0.0) && (globals.Flash.min_pw[i] > 0.0)) || ChannelStateToTest[i].zout<0) { report_error=Negative_Not_Allowed; } /* ------------------------------- */ /* --- check burst count settings --- */ if (globals.Flash.max_burst_count[i]>1) { /* --- check minimum setting --- */ if ( (!globals.Flash.burst_func[i] && ChannelStateToTest[i].burst_count<1) || (globals.Flash.burst_func[i] && ChannelStateToTest[i].burst_count<0)) { report_error=IllegalParameter; } /* --- check maximum setting --- */ globals.Constraints.err_max_burst_count[i]=globals.Flash.max_burst_count[i]; if (ChannelStateToTest[i].burst_count>globals.Constraints.err_max_burst_count[i]) { report_error=max_burst_count_error; } if (!globals.Flash.burst_func[i]) { if (globals.Flash.min_pw[i] > 0.0) { temp = (ChannelStateToTest[i].frequency * ampl_fixed_max_duty) / (ChannelStateToTest[i].pw * 100.0); if (temp < (float) globals.Constraints.err_max_burst_count[i]) { globals.Constraints.err_max_burst_count[i] = (int) temp; if ( (ChannelStateToTest[i].burst_count>globals.Constraints.err_max_burst_count[i]) && (ChannelStateToTest[i].burst_count>1)) { report_error=max_burst_count_error; } } temp = (1.0/ChannelStateToTest[i].frequency) / (ChannelStateToTest[i].pw+ChannelStateToTest[i].burst_time); if (temp < (float) globals.Constraints.err_max_burst_count[i]) { globals.Constraints.err_max_burst_count[i] = (int) temp; if ( (ChannelStateToTest[i].burst_count>globals.Constraints.err_max_burst_count[i]) && (ChannelStateToTest[i].burst_count>1)) { report_error=Burst_Exceeds_Period; } } } /* --- check minimum burst gap settings --- */ globals.Constraints.err_min_burst_time[i]=globals.Flash.min_burst_gap[i]; if ( (ChannelStateToTest[i].burst_count>1) && (ChannelStateToTest[i].burst_time<(0.999*globals.Constraints.err_min_burst_time[i]))) { report_error=min_burst_gap_error; } /* --- check minimum burst period settings --- */ if (globals.Flash.min_pw[i] > 0.0) { temp = globals.Flash.min_burst_per[i] - ChannelStateToTest[i].pw; if (temp > globals.Constraints.err_min_burst_time[i]) { globals.Constraints.err_min_burst_time[i] = temp; if ( (ChannelStateToTest[i].burst_count>1) && (ChannelStateToTest[i].burst_time<(0.999*globals.Constraints.err_min_burst_time[i]))) { report_error=min_burst_period_error; } } /* only report error when burst count is > 1, otherwise it gets annoying */ temp = ChannelStateToTest[i].pw * (100.0/globals.Flash.max_burst_duty[i] - 1.0); if (temp > globals.Constraints.err_min_burst_time[i]) { globals.Constraints.err_min_burst_time[i] = temp; if ( (ChannelStateToTest[i].burst_time<(0.999*globals.Constraints.err_min_burst_time[i])) && (ChannelStateToTest[i].burst_count>1)) { report_error=burst_duty_error; } } } /* --- check maximum burst gap settings --- */ globals.Constraints.err_max_burst_time[i]=globals.Flash.max_burst_gap[i]; if ( (ChannelStateToTest[i].burst_count>1) && (ChannelStateToTest[i].burst_time>(1.001*globals.Constraints.err_max_burst_time[i]))) { report_error=max_burst_gap_error; } } } /* --- check rise time settings --- */ /* disable amplitude checks if calibration is in progress */ if (!globals.Flash.fixed_rise_time[i]) if (!globals.Flags.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.Flags.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 ---- */ } g_static_mutex_unlock (&mutex); return report_error; }