summaryrefslogtreecommitdiff
path: root/device-functions.c
diff options
context:
space:
mode:
Diffstat (limited to 'device-functions.c')
-rw-r--r--device-functions.c462
1 files changed, 0 insertions, 462 deletions
diff --git a/device-functions.c b/device-functions.c
index e1ec380..3b1bf22 100644
--- a/device-functions.c
+++ b/device-functions.c
@@ -111,9 +111,6 @@ void Main_Rst (void)
globals.ChannelState[i].burst_time = globals.Constraints.composite_min_burst_time[i];
globals.ChannelState[i].rise_time = globals.Flash.min_rise_time[i];
globals.ChannelState[i].soft_current_limit = globals.Flash.max_soft_current_limit[i];
- globals.ChannelState[i].vcc1 = 0.0;
- globals.ChannelState[i].vcc2 = globals.Flash.vcc2_min[i];
- globals.ChannelState[i].vlogic = 0.0;
globals.ChannelState[i].slew = globals.Flash.min_slew[i];
globals.Flags.do_check_settings=NO; /* don't check for conflicting settings */
@@ -154,9 +151,6 @@ void Main_Rst (void)
Set_current_limit(0,i,globals.ChannelState[i].soft_current_limit);
- Set_avrq_ampl(0,0,0,2,globals.ChannelState[i].vcc1);
- Set_avrq_ampl(0,0,0,3,globals.ChannelState[i].vcc2);
- Set_avrq_ampl(0,0,0,4,globals.ChannelState[i].vlogic);
globals.Flags.do_check_settings=YES; /* check for conflicting settings */
}
@@ -199,18 +193,6 @@ int Set_Amplitude(int check_possible_only,int pol_override,int override_on,int w
new_ampl = fabs(new_ampl);
}
- if (globals.Flash.enable_avrq_extra_ampls && channel) {
- return Set_avrq_ampl(check_possible_only,word_override,range_override,channel,new_ampl);
- }
- if (globals.Flash.enable_avrq_extra_ampls && !channel) {
- if ((new_ampl>=0.0) && (new_ampl<globals.Flash.ampl_zero_equiv[channel])) {
- new_ampl=globals.Flash.ampl_zero_equiv[channel];
- }
- if ((new_ampl<0.0) && (new_ampl>-globals.Flash.ampl_zero_equiv[channel])) {
- new_ampl=-globals.Flash.ampl_zero_equiv[channel];
- }
- }
-
if (!globals.Flash.voltage_enabled[channel] && !globals.Flash.current_enabled[channel]) {
return Unrecognized;
}
@@ -1289,10 +1271,6 @@ int Set_Load(int channel, float value)
return InvalidChannel;
}
- if (globals.Flash.enable_avrq_extra_ampls) {
- return Set_avrq_res(0,0,0,channel,value);
- }
-
/* duty cycle check */
int i;
for (i=0; i<max_channels; ++i) {
@@ -1544,12 +1522,6 @@ int Set_Update_Chans(void)
globals.ChannelState[i].slew=globals.ChannelState[0].slew;
}
- for (i=1; i<num_of_chan; ++i) {
- globals.ChannelState[i].vcc1=globals.ChannelState[0].vcc1;
- globals.ChannelState[i].vcc2=globals.ChannelState[0].vcc2;
- globals.ChannelState[i].vlogic=globals.ChannelState[0].vlogic;
- }
-
}
return OK;
@@ -1990,22 +1962,6 @@ int Set_Cal_Nom(int channel,int calibration_point_number,int parameter, float *n
nominal_val=globals.Flash.slew_pwl_time[channel][range][polarity][entry];
nominal_wordout=globals.Flash.slew_pwl_Vc_norm4095[channel][range][polarity][entry];
break;
- case pwl_vcc1_values:
- nominal_val=globals.Flash.vcc1_pwl_amp[0][0][0][entry];
- nominal_wordout=globals.Flash.vcc1_pwl_Vc_norm4095[0][0][0][entry];
- true_channel=0;
- break;
- case pwl_vcc2_values:
- nominal_val=globals.Flash.vcc2_pwl_amp[0][0][0][entry];
- nominal_wordout=globals.Flash.vcc2_pwl_Vc_norm4095[0][0][0][entry];
- true_channel=0;
- break;
- case pwl_load_type_values:
- nominal_val=globals.Flash.load_type_pwl_time[channel][range][polarity][entry];
- nominal_wordout=globals.Flash.load_type_pwl_Vc_norm4095[channel][range][polarity][entry];
- reset_state=0;
- disable_errors=1;
- break;
}
/* just get nominal value, don't activate */
@@ -2128,18 +2084,6 @@ int Set_Cal_Nom(int channel,int calibration_point_number,int parameter, float *n
}
break;
- case pwl_load_type_values:
- Set_avrq_res(0,nominal_wordout,range,channel,nominal_val);
- break;
-
- case pwl_vcc1_values:
- status=Set_Amplitude(0,polarity,1,nominal_wordout,range,0,channel,nominal_val,0);
- break;
-
- case pwl_vcc2_values:
- status=Set_Amplitude(0,polarity,1,nominal_wordout,range,0,channel,nominal_val,0);
- break;
-
}
/* enables or disables delay diagnostic mode */
@@ -2215,23 +2159,6 @@ int Set_VI_Cal_Pnt(int parameter,int channel,int calibration_point_number,float
max_ranges=timing_ranges;
pwl_amp=&globals.Flash.slew_pwl_time[0][0][0][0];
break;
- case pwl_vcc1_values:
- max_polarity=1;
- max_ranges=1;
- true_channel=0;
- pwl_amp=&globals.Flash.vcc1_pwl_amp[0][0][0][0];
- break;
- case pwl_vcc2_values:
- max_polarity=1;
- max_ranges=1;
- true_channel=0;
- pwl_amp=&globals.Flash.vcc2_pwl_amp[0][0][0][0];
- break;
- case pwl_load_type_values:
- max_polarity=load_type_polarities;
- max_ranges=load_type_ranges;
- pwl_amp=&globals.Flash.load_type_pwl_time[0][0][0][0];
- break;
}
index=true_channel*max_ranges*max_polarity*max_points
+range*max_polarity*max_points
@@ -2275,7 +2202,6 @@ int Set_VI_Cal_Pnt(int parameter,int channel,int calibration_point_number,float
case pwl_burst_values:
case pwl_rise_time_values:
case pwl_slew_values:
- case pwl_load_type_values:
/* exclude relative changes of 45% or more unless < 15 ns */
if ( (fabs(cal_point-nom_ampl)/nom_ampl > 0.45) && (fabs(cal_point-nom_ampl)>15e-9)) {
return CalibrationPercentError;
@@ -2292,15 +2218,6 @@ int Set_VI_Cal_Pnt(int parameter,int channel,int calibration_point_number,float
}
break;
- case pwl_vcc1_values:
- case pwl_vcc2_values:
- if (fabs(nom_ampl) > smallest_allowed_number) {
- /* exclude relative changes of 30% or more */
- if (fabs( (cal_point-nom_ampl)/nom_ampl) > 0.3) {
- return CalibrationPercentError;
- }
- }
- break;
}
@@ -2416,32 +2333,6 @@ int Set_VI_Del_Cal(int parameter,int channel,int calibration_point_number)
size_of_short1=sizeof(globals.Flash.slew_pwl_Vc_norm4095);
size_of_float1=sizeof(globals.Flash.slew_pwl_time);
break;
- case pwl_vcc1_values:
- max_polarity=1;
- max_ranges=1;
- pointer_short1=&globals.Flash.vcc1_pwl_Vc_norm4095[0][0][0][0];
- pointer_float1=&globals.Flash.vcc1_pwl_amp[0][0][0][0];
- size_of_short1=sizeof(globals.Flash.vcc1_pwl_Vc_norm4095);
- size_of_float1=sizeof(globals.Flash.vcc1_pwl_amp);
- true_channel=0;
- break;
- case pwl_vcc2_values:
- max_polarity=1;
- max_ranges=1;
- pointer_short1=&globals.Flash.vcc2_pwl_Vc_norm4095[0][0][0][0];
- pointer_float1=&globals.Flash.vcc2_pwl_amp[0][0][0][0];
- size_of_short1=sizeof(globals.Flash.vcc2_pwl_Vc_norm4095);
- size_of_float1=sizeof(globals.Flash.vcc2_pwl_amp);
- true_channel=0;
- break;
- case pwl_load_type_values:
- max_polarity=load_type_polarities;
- max_ranges=load_type_ranges;
- pointer_short1=&globals.Flash.load_type_pwl_Vc_norm4095[0][0][0][0];
- pointer_float1=&globals.Flash.load_type_pwl_time[0][0][0][0];
- size_of_short1=sizeof(globals.Flash.load_type_pwl_Vc_norm4095);
- size_of_float1=sizeof(globals.Flash.load_type_pwl_time);
- break;
}
Get_VI_Rng_Info(parameter,channel,calibration_point_number,&range,&polarity,&entry,&num_in_range,&num_of_ranges);
@@ -2737,34 +2628,6 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
timing_extrapolation_allowed=NO;
top_range_only=YES; /* higher drive voltage = lower ripple in slew */
break;
- case pwl_vcc1_values:
- max_polarity=1;
- max_ranges=1;
- pwl_vc=&globals.Flash.vcc1_pwl_Vc_norm4095[0][0][0][0];
- pwl_amp=&globals.Flash.vcc1_pwl_amp[0][0][0][0];
- *UseNegData=0;
- use_ampl=new_ampl;
- true_channel=0;
- break;
- case pwl_vcc2_values:
- max_polarity=1;
- max_ranges=1;
- pwl_vc=&globals.Flash.vcc2_pwl_Vc_norm4095[0][0][0][0];
- pwl_amp=&globals.Flash.vcc2_pwl_amp[0][0][0][0];
- *UseNegData=0;
- use_ampl=new_ampl;
- true_channel=0;
- break;
- case pwl_load_type_values:
- max_polarity=load_type_polarities;
- max_ranges=load_type_ranges;
- pwl_vc=&globals.Flash.load_type_pwl_Vc_norm4095[0][0][0][0];
- pwl_amp=&globals.Flash.load_type_pwl_time[0][0][0][0];
- *UseNegData=0;
- use_ampl=new_ampl;
- reciprocal_relationship=YES;
- timing_extrapolation_allowed=YES;
- break;
}
@@ -3095,41 +2958,6 @@ int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
Set_VI_Control(pwl_slew_values,channel,old_val,&point_found,
&range,&atten_range,&polarity,&entry,&word_out,&actual_pol);
break;
- case pwl_vcc1_values:
- max_polarity=1;
- max_ranges=1;
- true_channel=0;
- pointer_x_short=&globals.Flash.vcc1_pwl_Vc_norm4095[0][0][0][0];
- pointer_y_float=&globals.Flash.vcc1_pwl_amp[0][0][0][0];
- size_of_x_short=sizeof(globals.Flash.vcc1_pwl_Vc_norm4095);
- size_of_y_float=sizeof(globals.Flash.vcc1_pwl_amp);
- old_val=globals.ChannelState[true_channel].vcc1;
- Set_VI_Control(pwl_vcc1_values,channel,old_val,&point_found,
- &range,&atten_range,&polarity,&entry,&word_out,&actual_pol);
- break;
- case pwl_vcc2_values:
- max_polarity=1;
- max_ranges=1;
- true_channel=0;
- pointer_x_short=&globals.Flash.vcc2_pwl_Vc_norm4095[0][0][0][0];
- pointer_y_float=&globals.Flash.vcc2_pwl_amp[0][0][0][0];
- size_of_x_short=sizeof(globals.Flash.vcc2_pwl_Vc_norm4095);
- size_of_y_float=sizeof(globals.Flash.vcc2_pwl_amp);
- old_val=globals.ChannelState[true_channel].vcc2;
- Set_VI_Control(pwl_vcc2_values,channel,old_val,&point_found,
- &range,&atten_range,&polarity,&entry,&word_out,&actual_pol);
- break;
- case pwl_load_type_values:
- max_polarity=load_type_polarities;
- max_ranges=load_type_ranges;
- pointer_x_short=&globals.Flash.load_type_pwl_Vc_norm4095[0][0][0][0];
- pointer_y_float=&globals.Flash.load_type_pwl_time[0][0][0][0];
- size_of_x_short=sizeof(globals.Flash.load_type_pwl_Vc_norm4095);
- size_of_y_float=sizeof(globals.Flash.load_type_pwl_time);
- old_val=globals.ChannelState[channel].load_type;
- Set_VI_Control(pwl_load_type_values,channel,old_val,&point_found,
- &range,&atten_range,&polarity,&entry,&word_out,&actual_pol);
- break;
}
@@ -3239,8 +3067,6 @@ int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
/* update output */
switch (parameter) {
case (pwl_ampl_values):
- case (pwl_vcc1_values):
- case (pwl_vcc2_values):
Set_Amplitude(0,0,0,0,0,0,channel,cal_point,0);
break;
@@ -3271,10 +3097,6 @@ int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
case pwl_slew_values:
Set_slew(0,0,0,channel,cal_point);
break;
-
- case pwl_load_type_values:
- Set_avrq_res(0,0,0,channel,cal_point);
- break;
}
return OK;
@@ -3351,23 +3173,6 @@ int Get_VI_Rng_Info(int parameter, int channel, int calibration_point_number, in
max_ranges=timing_ranges;
pwl=&globals.Flash.slew_pwl_time[0][0][0][0];
break;
- case pwl_vcc1_values:
- max_polarity=1;
- max_ranges=1;
- pwl=&globals.Flash.vcc1_pwl_amp[0][0][0][0];
- true_channel=0;
- break;
- case pwl_vcc2_values:
- max_polarity=1;
- max_ranges=1;
- pwl=&globals.Flash.vcc2_pwl_amp[0][0][0][0];
- true_channel=0;
- break;
- case pwl_load_type_values:
- max_polarity=load_type_polarities;
- max_ranges=load_type_ranges;
- pwl=&globals.Flash.load_type_pwl_time[0][0][0][0];
- break;
}
@@ -3464,20 +3269,6 @@ int Check_MinMax_Cal(int channel,int parameter)
|| Set_slew(1,0,0,channel,globals.Flash.max_slew[channel]);
break;
- case (pwl_vcc1_values):
- status=Set_Amplitude(1,0,0,0,0,0,channel,0.0,0)
- || Set_Amplitude(1,0,0,0,0,0,channel,globals.Flash.vcc1_max[0],0);
- break;
-
- case (pwl_vcc2_values):
- status=Set_Amplitude(1,0,0,0,0,0,channel,0.0,0)
- || Set_Amplitude(1,0,0,0,0,0,channel,globals.Flash.vcc2_max[0],0);
- break;
-
- case pwl_load_type_values:
- status=Set_avrq_res(1,0,0,channel,globals.Flash.low_load_type[channel])
- || Set_avrq_res(1,0,0,channel,globals.Flash.high_load_type[channel]);
- break;
}
if (status) {
@@ -3838,80 +3629,6 @@ int Set_current_limit(int check_possible_only,int channel,float new_adj_current_
}
-int Set_avrq_res(int check_possible_only,int word_override,int range_override,int channel,float new_res)
-{
- int point_found,relay_range,UseNegData,entry,actual_pol,word_out,dummy;
-
- if (!globals.Flash.switchable_load[channel]) {
- return Unrecognized;
- }
-
- /* abandon if high channel selected by user but not enabled by firmware */
- if (channel && !globals.Flash.ChanKey_load_type) {
- return InvalidChannel;
- }
-
- if (!check_possible_only) {
- int i, check_valid;
-
- for (i=0; i<max_channels; ++i) {
- TestState[i]=globals.ChannelState[i];
- }
- TestState[channel].load_type=new_res;
- if ((check_valid=Error_check(TestState))) {
- return check_valid;
- }
- }
-
- /* find appropriate range/fine settings from piece-wise linear data in flash memory */
- if (word_override) {
- word_out=word_override;
- relay_range=range_override;
- } else {
- /* ugly hack - fix me?
- CH2 = opto VCC
- Calibrate res at 3.0V
- Compensate for >3.0V */
- float compensated_new_res;
-
- if (globals.ChannelState[0].vcc2 > 0.0) {
- compensated_new_res = new_res * 3.0/globals.ChannelState[0].vcc2;
- } else {
- return amplitude_lower_limit;
- }
-
- int status;
- if ((status=Set_VI_Control(pwl_load_type_values,channel,compensated_new_res,&point_found,
- &relay_range,&dummy,&UseNegData,&entry,&word_out,&actual_pol))) {
- return status;
- }
- }
-
- if (check_possible_only) {
- if (point_found) {
- return OK;
- } else {
- return CalibrationMinMaxError;
- }
- }
-
- set_dac(globals.Flash.load_type_dac[channel],word_out);
-
- /* no ranges are used */
-
- /* update variables if OK */
- if (new_res!=globals.ChannelState[channel].load_type) {
- globals.Changes.update_load=YES;
- }
-
- globals.ChannelState[channel].load_type = new_res;
-
- Set_Update_Chans();
-
- return OK;
-}
-
-
int Set_slew(int check_possible_only,int word_override,int range_override,int channel,float new_slew)
{
int check_valid;
@@ -3989,174 +3706,6 @@ int Set_slew(int check_possible_only,int word_override,int range_override,int ch
}
-int Set_avrq_ampl(int check_possible_only,int word_override,int range_override,int channel,float new_avrq_ampl)
-{
- int check_valid;
- int status,point_found,relay_range,UseNegData,entry,actual_pol,word_out,dummy;
- int true_channel;
- int use_pwl;
-
- if (!globals.Flash.enable_avrq_extra_ampls) {
- return Unrecognized;
- }
-
- /* check channels */
- if ((channel < 1) || (channel>4)) {
- return InvalidChannel;
- }
-
- if (channel == 1) {
- true_channel = 1;
- } else {
- true_channel = 0;
- }
-
- if (!check_possible_only) {
- /* check duty cycle */
- int i;
- for (i=0; i<max_channels; ++i) {
- TestState[i]=globals.ChannelState[i];
- }
- switch (channel) {
- case 1:
- TestState[true_channel].amplitude=new_avrq_ampl;
- break;
- case 2:
- TestState[true_channel].vcc1=new_avrq_ampl;
- if (TestState[true_channel].vlogic >= smallest_allowed_number) {
- TestState[true_channel].vlogic = new_avrq_ampl;
- }
- break;
- case 3:
- TestState[true_channel].vcc2=new_avrq_ampl;
- break;
- case 4:
- TestState[true_channel].vlogic=new_avrq_ampl;
- break;
- }
- if ((check_valid=Error_check(TestState))) {
- return check_valid;
- }
- }
-
- /* find appropriate range/fine settings from piece-wise linear data in flash memory */
- if (word_override) {
- word_out=word_override;
- relay_range=range_override;
- } else {
- switch (channel) {
- case 1:
- use_pwl = pwl_ampl_values;
- break;
- case 2:
- use_pwl = pwl_vcc1_values;
- break;
- case 3:
- use_pwl = pwl_vcc2_values;
- break;
- case 4:
- use_pwl = pwl_vlogic_values;
- if (new_avrq_ampl > 0.0) {
- new_avrq_ampl = globals.ChannelState[true_channel].vcc1;
- }
- break;
- }
-
- if (use_pwl != pwl_vlogic_values)
- if ((status=Set_VI_Control(use_pwl,channel,new_avrq_ampl,&point_found,&relay_range,&dummy,&UseNegData,&entry,&word_out,&actual_pol))) {
- return status;
- }
-
- }
-
- if (check_possible_only) {
- if (point_found) {
- return OK;
- } else {
- return CalibrationMinMaxError;
- }
- }
-
-
- /* update variables if OK */
- switch (channel) {
- case 1:
- Set_avrq_ampl(0,0,0,4,0.0);
-
- set_dac(1,word_out);
-
- globals.Registers.avrq_reg = globals.Registers.avrq_reg & 0x3f;
- I2C_Write(PCF8574A+rise_time_port,globals.Registers.avrq_reg);
-
- if (new_avrq_ampl!=globals.ChannelState[true_channel].amplitude) {
- globals.Changes.update_amp=YES;
- }
- globals.ChannelState[true_channel].amplitude=new_avrq_ampl;
- break;
- case 2:
- set_dac(1,word_out);
-
- globals.Registers.avrq_reg = 0x40 | (globals.Registers.avrq_reg & 0xbf);
- I2C_Write(PCF8574A+rise_time_port,globals.Registers.avrq_reg);
-
- if (new_avrq_ampl!=globals.ChannelState[true_channel].vcc1) {
- globals.Changes.update_amp=YES;
- }
- globals.ChannelState[true_channel].vcc1=new_avrq_ampl;
- break;
- case 3:
- set_dac(0,word_out);
- if (new_avrq_ampl!=globals.ChannelState[true_channel].vcc2) {
- globals.Changes.update_amp=YES;
- }
- globals.ChannelState[true_channel].vcc2=new_avrq_ampl;
-
- /* update ampl-dependent load resistance */
- Set_avrq_res(0,0,0,0,globals.ChannelState[0].load_type);
-
- break;
- case 4:
- if (new_avrq_ampl >= smallest_allowed_number) {
- relay_range = 0x80;
- } else {
- relay_range = 0x0;
- }
- globals.Registers.avrq_reg = relay_range | (globals.Registers.avrq_reg & 0x7f);
- I2C_Write(PCF8574A+rise_time_port,globals.Registers.avrq_reg);
-
- if (new_avrq_ampl!=globals.ChannelState[true_channel].vlogic) {
- globals.Changes.update_amp=YES;
- }
- globals.ChannelState[true_channel].vlogic=new_avrq_ampl;
- break;
- }
-
-
- /* reduce vlogic based on vcc1, if required */
- if (channel == 2) {
- if (globals.ChannelState[true_channel].vlogic > smallest_allowed_number) {
- Set_avrq_ampl(0,0,0,4,globals.ChannelState[true_channel].vcc1);
- } else {
- Set_avrq_ampl(0,0,0,4,0.0);
- }
- }
-
- /* reduce vcc1 if ibias is active, because they share a DAC */
- if ((channel == 1) && (globals.ChannelState[true_channel].amplitude > smallest_allowed_number)) {
- globals.ChannelState[0].vcc1=0.0;
- }
-
- /* reduce vcc1 if ibias is active, because they share a DAC */
- if ((channel == 2) && (globals.ChannelState[true_channel].vcc1 > smallest_allowed_number)) {
- globals.ChannelState[1].amplitude=0.0;
- }
-
- Set_Update_Chans();
-
- return OK;
-}
-
-
int go_cal(CalStruct *caldata)
{
int i, status, points;
@@ -4531,10 +4080,6 @@ void Set_Rcl(int setting_num)
globals.ChannelState[i].rise_time=globals.Flash.rcl_rise_time[i][setting_num];
globals.ChannelState[i].slew=globals.Flash.rcl_slew[i][setting_num];
- globals.ChannelState[i].vcc1=globals.Flash.rcl_vcc1[i][setting_num];
- globals.ChannelState[i].vcc2=globals.Flash.rcl_vcc2[i][setting_num];
- globals.ChannelState[i].vlogic=globals.Flash.rcl_vlogic[i][setting_num];
-
globals.ChannelState[i].soft_current_limit=globals.Flash.rcl_soft_current_limit[i][setting_num];
globals.ChannelState[i].load_type=globals.Flash.rcl_load[i][setting_num];
@@ -4602,10 +4147,6 @@ void Set_Rcl(int setting_num)
Set_Offset(0,0,0,0,i,globals.ChannelState[i].offset);
}
- Set_avrq_ampl(0,0,0,2,globals.ChannelState[i].vcc1);
- Set_avrq_ampl(0,0,0,3,globals.ChannelState[i].vcc2);
- Set_avrq_ampl(0,0,0,4,globals.ChannelState[i].vlogic);
-
Set_Output_State(i,globals.ChannelState[i].output_state);
}
@@ -4642,9 +4183,6 @@ void Set_Sav(int setting_num)
globals.Flash.rcl_slew[i][setting_num]=globals.ChannelState[i].slew;
globals.Flash.rcl_soft_current_limit[i][setting_num]=globals.ChannelState[i].soft_current_limit;
globals.Flash.rcl_load[i][setting_num]=globals.ChannelState[i].load_type;
- globals.Flash.rcl_vcc1[i][setting_num]=globals.ChannelState[i].vcc1;
- globals.Flash.rcl_vcc2[i][setting_num]=globals.ChannelState[i].vcc2;
- globals.Flash.rcl_vlogic[i][setting_num]=globals.ChannelState[i].vlogic;
/* integers setting_nums
globals.ChannelState[i].zout 50 (1) or min (0)