From 845fc78831dedcf1f0c529c1302cb04fead7acb6 Mon Sep 17 00:00:00 2001
From: Mike <mjc@avtechpulse.com>
Date: Sat, 1 Jan 2000 01:25:54 +0900
Subject: Major reworking. Set_VI_Control now stores its calculation results
 for later reference. This fixes the problem of adding cal points to
 parameters with large adjustments. The x values are now correct, but the user
 must still manually compensate for y changes.

---
 device-functions.c | 503 ++++++++++++++++++++++++++---------------------------
 device-functions.h |   3 +-
 globals.c          |  18 ++
 globals.h          |  33 +++-
 monitor.c          |   7 +-
 5 files changed, 292 insertions(+), 272 deletions(-)

diff --git a/device-functions.c b/device-functions.c
index d14f513..d3a5bef 100644
--- a/device-functions.c
+++ b/device-functions.c
@@ -254,12 +254,9 @@ static int attenuator_count (int channel)
 int Set_Amplitude(int check_possible_only,int pol_override,int override_on,int word_override,int range_override,int aux_override,
                   int switch_range_only,int channel,float requested_ampl,int called_from_set_pw)
 {
-	int word_out, word_out_aux;	  /* what is sent to the DAC */
-	int relay_range,atten_range,old_range,old_actual_pol;	  /* selects relay range */
-	int UseNegData;	/* if polarity is negative and separate piece-wise linear data is available for neg */
-	int point_found;
-	int entry;
-	int actual_pol;
+	const int parameter = pwl_ampl_values;
+
+	int old_range,old_actual_pol;	  /* selects relay range */
 
 	float new_ampl;
 
@@ -318,32 +315,27 @@ int Set_Amplitude(int check_possible_only,int pol_override,int override_on,int w
 		}
 
 		/* determine the previous relay range */
-		Set_VI_Control(pwl_ampl_values,channel,globals.ChannelState[channel].amplitude,&point_found,
-		               &old_range,&atten_range,&UseNegData,&entry,&word_out,&old_actual_pol,NULL);
+		old_range = pwl_struct[parameter][channel].range;
+		old_actual_pol = pwl_struct[parameter][channel].actual_pol;
 	}
 
-	word_out = -1;
-	relay_range = 0;
-
-
 	/* find appropriate range/fine settings from piece-wise linear data in flash memory */
 
 	if (override_on) {
-		word_out=word_override;
-		relay_range=range_override;
-		actual_pol=pol_override;
-		word_out_aux=aux_override;
+		pwl_struct[parameter][channel].word_out=word_override;
+		pwl_struct[parameter][channel].range=range_override;
+		pwl_struct[parameter][channel].actual_pol=pol_override;
+		pwl_struct[parameter][channel].word_out_aux=aux_override;
 	} else {
 		/* set the amplitude controls now. */
 		int status;
-		if ((status=Set_VI_Control(pwl_ampl_values,channel,new_ampl,&point_found,
-		                           &relay_range,&atten_range,&UseNegData,&entry,&word_out,&actual_pol,&word_out_aux))) {
+		if (status=Set_VI_Control(parameter,channel,new_ampl)) {
 			return status;
 		}
 	}
 
 	if (check_possible_only) {
-		if (point_found) {
+		if (pwl_struct[parameter][channel].point_found) {
 			return OK;
 		} else {
 			return CalibrationMinMaxError_ampl;
@@ -352,35 +344,36 @@ int Set_Amplitude(int check_possible_only,int pol_override,int override_on,int w
 
 	/* when switching to EA mode, need to switch range but keep DAC voltage zero */
 	if (switch_range_only) {
-		word_out=0;
+		pwl_struct[parameter][channel].word_out=0;
 	}
 
 
 	/* if switching to a higher range with the same polarity, an extended delay may be needed to allow */
 	/* capacitor banks to discharge (1011, 1015 series especially) */
-	if ((relay_range>old_range) && (actual_pol==old_actual_pol) ) {
+	if (	(pwl_struct[parameter][channel].range > old_range)
+		 && (pwl_struct[parameter][channel].actual_pol == old_actual_pol) ) {
 		globals.Timers.Relay_Switching_Delay_in_Milliseconds=(long) (1000L * globals.Flash.extended_relay_delay_in_sec);
 	}
 
 	if (globals.Flash.distort_enabled[channel]) {
-		set_dac(globals.Flash.distort_dac[channel],word_out_aux);
+		set_dac(globals.Flash.distort_dac[channel],pwl_struct[parameter][channel].word_out_aux);
 	}
 
-	set_dac(globals.Flash.ampl_DAC[channel],word_out);
+	set_dac(globals.Flash.ampl_DAC[channel],pwl_struct[parameter][channel].word_out);
 
 	if (!channel) {
 		if (!globals.Flash.ampl_ranges_for_ch2_only) {
 			if ((globals.Flash.ChanKey_amplitude?globals.Flash.channels:1)<=1) {
 				/* for regular, single-channel units use AMPL RANGE pins 0-4 */
-				set_shiftreg_bits(SR_3, POS_7, FIVE_BITS, 1<<relay_range);
+				set_shiftreg_bits(SR_3, POS_7, FIVE_BITS, 1 << pwl_struct[parameter][channel].range);
 			} else {
 				/* for CH1 of dual-channel units, use AMPL RANGE pin 0-2 for CH1, and 3-4 for CH2 */
-				set_shiftreg_bits(SR_3, POS_7, THREE_BITS, 1<<relay_range);
+				set_shiftreg_bits(SR_3, POS_7, THREE_BITS,  1 << pwl_struct[parameter][channel].range);
 			}
 		}
 
-		if (	(!actual_pol && globals.Flash.pol_relay_high_for_pos[channel])
-		                ||	(actual_pol && !globals.Flash.pol_relay_high_for_pos[channel])	) {
+		if (	(!pwl_struct[parameter][channel].actual_pol && globals.Flash.pol_relay_high_for_pos[channel])
+		                ||	(pwl_struct[parameter][channel].actual_pol && !globals.Flash.pol_relay_high_for_pos[channel])	) {
 			set_shiftreg_bits(SR_3, POS_13, ONE_BIT, BIT_HIGH);	/* set O.POL line high to switch pol relay to +, normally */
 		} else {
 			set_shiftreg_bits(SR_3, POS_13, ONE_BIT, BIT_LOW);	/* set O.POL line low to switch pol relay to -, normally */
@@ -390,10 +383,10 @@ int Set_Amplitude(int check_possible_only,int pol_override,int override_on,int w
 	} else {
 		if (!globals.Flash.ampl_ranges_for_ch2_only) {
 			/* for CH2 of dual-channel units, use AMPL RANGE pin 2-3 */
-			set_shiftreg_bits(SR_3, POS_10, TWO_BITS, 1<<relay_range);
+			set_shiftreg_bits(SR_3, POS_10, TWO_BITS, 1 << pwl_struct[parameter][channel].range);
 		} else {
 			/* sometimes CH2 can use pins 0-4 */
-			set_shiftreg_bits(SR_3, POS_7, FIVE_BITS, 1<<relay_range);
+			set_shiftreg_bits(SR_3, POS_7, FIVE_BITS, 1 << pwl_struct[parameter][channel].range);
 		}
 
 		// only do this on dual-polarity dual-channel units
@@ -409,10 +402,11 @@ int Set_Amplitude(int check_possible_only,int pol_override,int override_on,int w
 
 	// Are attenuators used?
 	int atten_ctl = 0;
+	int adj_atten_range = pwl_struct[parameter][channel].atten_range;
 
 	if (attenuator_count(channel) == 1) {
 
-		if (atten_range == 0) {
+		if (adj_atten_range == 0) {
 			atten_ctl = BIT_HIGH;
 		} else {
 			atten_ctl = BIT_LOW;
@@ -424,22 +418,22 @@ int Set_Amplitude(int check_possible_only,int pol_override,int override_on,int w
 	} else if (attenuator_count(channel) > 1) {
 
 		// octal relay driver is inverted
-		if ((atten_range < 0) || (atten_range >= max_attens)) {
+		if ((adj_atten_range < 0) || (adj_atten_range >= max_attens)) {
 			atten_ctl = 0xff;
 		} else {
 			if (channel) {
 				// shift over 4 positions, out of 8, if CH2
-				atten_range += 4;
+				adj_atten_range += 4;
 			}
 
 			if (globals.Flash.sequential_attenuators[channel]) {
 				// For AVRZ-5W-B-LVA, which uses 3 identical 20 dB attenuators.
 				// 0, 1, 2 or 3 in series are used.
-				atten_ctl = ~((1 << (atten_range+1)) - 1);
+				atten_ctl = ~((1 << (adj_atten_range+1)) - 1);
 			} else {
 				// For more standard configurations, where different attenuators
 				// are combined in a binary style - 000, 001, 010, 011, 100, etc
-				atten_ctl = ~(atten_range+1);
+				atten_ctl = ~(adj_atten_range+1);
 			}
 		}
 
@@ -451,15 +445,13 @@ int Set_Amplitude(int check_possible_only,int pol_override,int override_on,int w
 		globals.Flags.force_output_fully_off=YES;
 	}
 
-	g_print_debug("chan %d, requested ampl %e, set ampl %e, polarity %d, range %d, word %d\n",
-		channel, requested_ampl, new_ampl, actual_pol, relay_range, word_out);
+	debug_new_parameter (channel, parameter, requested_ampl);
 
 	globals.Changes.update_amp=YES;
-
 	globals.ChannelState[channel].amplitude=new_ampl;
 	Set_Update_Chans();
 
-	if (relay_range!=old_range) {
+	if (pwl_struct[parameter][channel].range!=old_range) {
 		globals.Flags.force_output_fully_off=YES;
 	}
 
@@ -489,12 +481,13 @@ int Set_Amplitude(int check_possible_only,int pol_override,int override_on,int w
 }
 
 
-int Set_Pw(int check_possible_only,int word_override,int range_override,int channel,float set_pw,int called_from_set_ampl)
+int Set_Pw(int check_possible_only,int word_override,int range_override,int channel,float requested_pw, int called_from_set_ampl)
 {
-	int word_out;  /* what is sent to the DAC */
+	const int parameter = pwl_pw_values;
+
 	int cap_range_control;
-	int point_found,relay_range,dummy,UseNegData,entry;
-	int status,actual_pol;
+	int status;
+	float set_pw = requested_pw;
 
 	/* abandon if high channel selected by user but not enabled by firmware */
 	if (channel && !globals.Flash.ChanKey_pw) {
@@ -524,29 +517,28 @@ int Set_Pw(int check_possible_only,int word_override,int range_override,int chan
 
 	/* find appropriate range/fine settings from piece-wise linear data in flash memory */
 	if (word_override) {
-		word_out=word_override;
-		relay_range=range_override;
+		pwl_struct[parameter][channel].word_out=word_override;
+		pwl_struct[parameter][channel].range=range_override;
 	} else {
 		/* set the pw controls now. */
-		if ((status=Set_VI_Control(pwl_pw_values,channel,set_pw,&point_found,
-		                           &relay_range,&dummy,&UseNegData,&entry,&word_out,&actual_pol,NULL))) {
+		if (status=Set_VI_Control(parameter,channel,set_pw)) {
 			return status;
 		}
 	}
 
 
 	if (check_possible_only) {
-		if (point_found) {
+		if (pwl_struct[parameter][channel].point_found) {
 			return OK;
 		} else {
 			return CalibrationMinMaxError_pw;
 		}
 	}
 
-	if (relay_range==0) {
+	if (pwl_struct[parameter][channel].range==0) {
 		cap_range_control=0;
 	} else {
-		cap_range_control = 1 << (relay_range-1);
+		cap_range_control = 1 << (pwl_struct[parameter][channel].range-1);
 	}
 
 	/* if this is for CH1, use the standard output chain */
@@ -566,14 +558,9 @@ int Set_Pw(int check_possible_only,int word_override,int range_override,int chan
 			set_shiftreg_bits(SR_2, XTR_POS + 5, ONE_BIT, BIT_LOW);
 
 			/* use DAC8420 to control PW in lowest PW range */
-			if (!relay_range) {
+			if (!pwl_struct[parameter][channel].range) {
 				// set the voltage to the actual PW-control circuit (normally in a module)
-				set_dac(globals.Flash.pw_dac[channel],word_out);
-
-				// This word is fed to the PW circuit on the OP1B board, not the module
-				// Set to a fixed value. Isn't actually used to control PW in this mode,
-				// but triggers following stages.
-				word_out=globals.Flash.fix_pw_dac_val[channel];
+				set_dac(globals.Flash.pw_dac[channel],pwl_struct[parameter][channel].word_out);
 
 				// Also, boost the internal PW range during calibration
 				// so that PRF calibration works at
@@ -601,10 +588,12 @@ int Set_Pw(int check_possible_only,int word_override,int range_override,int chan
 				// value from above. Instead, the CH2 delay function controls the
 				// pulse width of the trigger signal. Obscure!
 				if (globals.Flash.min_delay[1] >= 0.0) {
-					set_dac(4,word_out);
+					// This word is fed to the PW circuit on the OP1B board, not the module
+					// Set to a fixed value. Isn't actually used to control PW in this mode,
+					// but triggers following stages.
+					set_dac(4,globals.Flash.fix_pw_dac_val[channel]);
 					set_shiftreg_bits(SR_3, POS_0, SEVEN_BITS, cap_range_control);
 				}
-
 			} else {
 				Set_Use_Vctrl_PW_Range(channel,FALSE);
 
@@ -612,20 +601,20 @@ int Set_Pw(int check_possible_only,int word_override,int range_override,int chan
 					PWin=PWout. Therefore, shift the relay used by the upper ranges by one, to avoid
 					changing capacitors. */
 
-				if (relay_range==1) {
+				if (pwl_struct[parameter][channel].range==1) {
 					cap_range_control=0;
 					// set XTRA RLY 5 high in this range for AVR-E3-B-R5-N-M5, and other
 					// units with PG A, B, and C. This corresponds to PG B.
 					set_shiftreg_bits(SR_2, XTR_POS + 5, ONE_BIT, BIT_HIGH);
 				} else {
-					cap_range_control = 1 << (relay_range-2);
+					cap_range_control = 1 << (pwl_struct[parameter][channel].range-2);
 				}
 
-				set_dac(4,word_out);
+				set_dac(4,pwl_struct[parameter][channel].word_out);
 				set_shiftreg_bits(SR_3, POS_0, SEVEN_BITS, cap_range_control);
 			}
 		} else {
-			set_dac(4,word_out);
+			set_dac(4,pwl_struct[parameter][channel].word_out);
 			set_shiftreg_bits(SR_3, POS_0, SEVEN_BITS, cap_range_control);
 		}
 	}
@@ -634,31 +623,27 @@ int Set_Pw(int check_possible_only,int word_override,int range_override,int chan
 		/* if this is for CH2, use the standard 1021D dual-PW board, which has a PCF8574 for I/O, */
 		/* unless it is a voltage-controlled scheme like the ISI units. */
 		if (!globals.Flash.volt_ctrl_pw[channel]) {
-			control_pcb107(Second_PW_Port,globals.Flash.pw_dac[channel],word_out,relay_range);
+			control_pcb107(Second_PW_Port,globals.Flash.pw_dac[channel],pwl_struct[parameter][channel].word_out,pwl_struct[parameter][channel].range);
 		} else {
 			/* ISI-style units have voltage-controlled PW and two ranges */
-			set_dac(globals.Flash.pw_dac[channel],word_out);
+			set_dac(globals.Flash.pw_dac[channel],pwl_struct[parameter][channel].word_out);
 
 			/* two ranges controlled by XTRA-RLY2 line */
-			set_shiftreg_bits(SR_2, XTR_POS + 2, ONE_BIT, relay_range);
+			set_shiftreg_bits(SR_2, XTR_POS + 2, ONE_BIT, pwl_struct[parameter][channel].range);
 		}
 	}
 
 	/* need a center-frequency control voltage for monocycle generators, to space the + and - parts of the monocycle. */
 	/* use CH2 calibration to do this */
-	if (globals.Flash.is_monocycle[0] && channel==0) {
-		if ((status=Set_VI_Control(pwl_pw_values,1,set_pw,&point_found,
-		                           &relay_range,&dummy,&UseNegData,&entry,&word_out,&actual_pol,NULL))) {
-			return status;
-		}
-		set_dac(globals.Flash.monocycle_dac[0],word_out);
+	if (globals.Flash.is_monocycle[channel]) {
+		return obsolete_feature;
 	}
 
+	debug_new_parameter (channel, parameter, requested_pw);
+
 	globals.ChannelState[channel].pw=set_pw;
 	Set_Update_Chans();
 
-	g_print_debug("chan %d, pw %e, range %d, word %d\n", channel, set_pw, relay_range, word_out);
-
 	if (!called_from_set_ampl) {
 		Set_Amplitude(0,0,0,0,0,0,0,channel,globals.ChannelState[channel].amplitude,1);
 	}
@@ -667,13 +652,13 @@ int Set_Pw(int check_possible_only,int word_override,int range_override,int chan
 }
 
 
-int Set_Offset(int check_possible_only,int override_on,int word_override,int range_override,int channel,float new_offset)
+int Set_Offset(int check_possible_only,int override_on,int word_override,int range_override,int channel,float requested_offset)
 {
-	int word_out;	  /* what is sent to the DAC */
-	int point_found;
-	int entry,dummy0,dummy1,dummy2,dummy3;
-	int actual_pol;
-	int old_range,relay_range;
+	const int parameter = pwl_os_values;
+
+	int old_range;
+
+	float new_offset = requested_offset;
 
 	if (!globals.Flash.voltage_offset_enabled[channel] && !globals.Flash.current_offset_enabled[channel]) {
 		return Unrecognized;
@@ -684,9 +669,6 @@ int Set_Offset(int check_possible_only,int override_on,int word_override,int ran
 		return InvalidChannel;
 	}
 
-	word_out = -1;
-	point_found = 0;
-
 	if (!check_possible_only) {
 		int i, error_num;
 		for (i=0; i<max_channels; ++i) {
@@ -698,37 +680,36 @@ int Set_Offset(int check_possible_only,int override_on,int word_override,int ran
 		}
 
 		/* determine the previous relay range */
-		Set_VI_Control(pwl_os_values,channel,globals.ChannelState[channel].offset,&point_found,
-		               &old_range,&dummy0,&dummy1,&dummy2,&word_out,&dummy3,NULL);
+                old_range = pwl_struct[parameter][channel].range;
 	}
 
 	if (override_on) {
-		relay_range=range_override;
-		word_out=word_override;
+		pwl_struct[parameter][channel].range=range_override;
+		pwl_struct[parameter][channel].word_out=word_override;
 	} else {
 		int status;
-		if ((status=Set_VI_Control(pwl_os_values,channel,new_offset,&point_found,
-		                           &relay_range,&dummy0,&dummy2,&entry,&word_out,&actual_pol,NULL))) {
+		if (status=Set_VI_Control(parameter,channel,new_offset)) {
 			return status;
 		}
 	}
 
 	if (check_possible_only) {
-		if (point_found) {
+		if (pwl_struct[parameter][channel].point_found) {
 			return OK;
 		} else {
 			return CalibrationMinMaxError_os;
 		}
 	}
 
-	set_dac(globals.Flash.os_DAC[channel],word_out);
+	set_dac(globals.Flash.os_DAC[channel],pwl_struct[parameter][channel].word_out);
 
-	globals.Changes.update_os=YES;
+	debug_new_parameter (channel, parameter, requested_offset);
 
+	globals.Changes.update_os=YES;
 	globals.ChannelState[channel].offset=new_offset;
 	Set_Update_Chans();
 
-	if (relay_range!=old_range) {
+	if (pwl_struct[parameter][channel].range!=old_range) {
 		globals.Flags.force_output_fully_off=YES;
 	}
 
@@ -738,7 +719,7 @@ int Set_Offset(int check_possible_only,int override_on,int word_override,int ran
 
 	/* change amplitude range if required for calibration */
 	if (override_on) {
-		Set_Amplitude(0,0,1,0,relay_range,0,0,channel,0.0,0);
+		Set_Amplitude(0,0,1,0,pwl_struct[parameter][channel].range,0,0,channel,0.0,0);
 	}
 
 	/* increase PW if required to compensate for series output diode turn-on time */
@@ -750,19 +731,19 @@ int Set_Offset(int check_possible_only,int override_on,int word_override,int ran
 }
 
 
-int Set_frequency(int check_possible_only,int word_override,int range_override,int channel,float set_freq)
+int Set_frequency(int check_possible_only,int word_override,int range_override,int channel,float requested_freq)
 {
+	const int parameter = pwl_period_values;
 	float new_pw;
-	int point_found,relay_range,UseNegData,entry,actual_pol,old_range,dummy;
-	int word_out;	/* what is sent to the DAC */
+	int old_range;
+
+	float set_freq = requested_freq;
 
 	/* abandon if high channel selected by user but not enabled by firmware */
 	if (channel && !globals.Flash.ChanKey_frequency) {
 		return InvalidChannel;
 	}
 
-	word_out = -1;
-
 	/* check new duty cycle, if pw fixed */
 	if (globals.ChannelState[channel].hold_setting==hold_width) {
 		new_pw=globals.ChannelState[channel].pw;
@@ -783,25 +764,23 @@ int Set_frequency(int check_possible_only,int word_override,int range_override,i
 
 		/* added Feb 23/05 */
 		/* determine the previous relay range */
-		Set_VI_Control(pwl_period_values,channel,1.0/globals.ChannelState[channel].frequency,&point_found,
-		               &old_range,&dummy,&UseNegData,&entry,&word_out,&actual_pol,NULL);
+		old_range = pwl_struct[parameter][channel].range;
 	}
 
 	/* find appropriate range/fine settings from piece-wise linear data in flash memory */
 	if (word_override) {
-		word_out=word_override;
-		relay_range=range_override;
+		pwl_struct[parameter][channel].word_out=word_override;
+		pwl_struct[parameter][channel].range=range_override;
 	} else {
 		/* set the amplitude controls now. */
 		int status;
-		if ((status=Set_VI_Control(pwl_period_values,channel,1.0/set_freq,&point_found,
-		                           &relay_range,&dummy,&UseNegData,&entry,&word_out,&actual_pol,NULL))) {
+		if (status=Set_VI_Control(parameter,channel,1.0/set_freq)) {
 			return status;
 		}
 	}
 
 	if (check_possible_only) {
-		if (point_found) {
+		if (pwl_struct[parameter][channel].point_found) {
 			return OK;
 		} else {
 			return CalibrationMinMaxError_freq;
@@ -809,18 +788,18 @@ int Set_frequency(int check_possible_only,int word_override,int range_override,i
 	}
 
 	if (globals.Flash.is_func_gen[channel]) {
-		set_dac(globals.Flash.freq_dac[channel],word_out);
+		set_dac(globals.Flash.freq_dac[channel],pwl_struct[parameter][channel].word_out);
 
 		/* Function generator PRF range controlled by XTRA-RLY 1-3 lines. */
 		/* Range=0 disables oscillator, for amplifier mode. */
 
 		if (globals.ChannelState[channel].func_mode==amp_mode_on) {
-			relay_range=0;
+			pwl_struct[parameter][channel].range=0;
 		}
 
-		set_shiftreg_bits(SR_2, XTR_POS + 1, THREE_BITS, relay_range);
+		set_shiftreg_bits(SR_2, XTR_POS + 1, THREE_BITS, pwl_struct[parameter][channel].range);
 
-		if (relay_range!=old_range) {
+		if (pwl_struct[parameter][channel].range!=old_range) {
 			globals.Flags.force_output_fully_off=YES;
 		}
 	}
@@ -828,18 +807,17 @@ int Set_frequency(int check_possible_only,int word_override,int range_override,i
 	else {
 		int cap_range_control = 0;
 
-		if (relay_range) {
-			cap_range_control = 1 << (relay_range-1);
+		if (pwl_struct[parameter][channel].range) {
+			cap_range_control = 1 << (pwl_struct[parameter][channel].range-1);
 		}
 
-		set_dac(globals.Flash.freq_dac[channel],word_out);
+		set_dac(globals.Flash.freq_dac[channel],pwl_struct[parameter][channel].word_out);
 		set_shiftreg_bits(SR_2, POS_0, SEVEN_BITS, cap_range_control);
 	}
 
-	g_print_debug("chan %d, freq %e, range %d, word %d\n", channel, set_freq, relay_range, word_out);
+	debug_new_parameter (channel, parameter, requested_freq);
 
 	globals.ChannelState[channel].frequency=set_freq;
-
 	Set_Pw(0,0,0,channel,new_pw,0);
 	Set_Update_Chans();
 
@@ -847,12 +825,14 @@ int Set_frequency(int check_possible_only,int word_override,int range_override,i
 }
 
 
-int Set_Delay(int check_possible_only,int word_override,int range_override,int channel,float set_delay)
+int Set_Delay(int check_possible_only,int word_override,int range_override,int channel,float requested_delay)
 {
-	int word_out;  /* what is sent to the DAC */
+	const int parameter = pwl_delay_values;
+
 	int cap_range_control;	/* what is actually sent to shift register */
-	float adj_setting, setting, min_one_shot_delay;
-	int point_found,relay_range,UseNegData,entry,actual_pol,dummy;
+	float setting, min_one_shot_delay;
+
+	float set_delay = requested_delay;
 
 	/* abandon if high channel selected by user but not enabled by firmware */
 	if (channel && !globals.Flash.ChanKey_delay) {
@@ -872,8 +852,8 @@ int Set_Delay(int check_possible_only,int word_override,int range_override,int c
 
 	/* find appropriate range/fine settings from piece-wise linear data in flash memory */
 	if (word_override) {
-		word_out=word_override;
-		relay_range=range_override;
+		pwl_struct[parameter][channel].word_out=word_override;
+		pwl_struct[parameter][channel].range=range_override;
 		Set_AdvDel(channel,to_Advance);
 	} else {
 
@@ -911,7 +891,7 @@ int Set_Delay(int check_possible_only,int word_override,int range_override,int c
 
 		if (!globals.Flash.volt_ctrl_delay[channel]) {
 			/* tweak depending on polarity */
-			adj_setting = set_delay;
+			float adj_setting = set_delay;
 			if (globals.ChannelState[channel].amplitude<0.0) {
 				adj_setting -= globals.Flash.delay_pol_tweak[channel][1];
 			} else {
@@ -935,14 +915,13 @@ int Set_Delay(int check_possible_only,int word_override,int range_override,int c
 
 		/* set the amplitude controls now. */
 		int status;
-		if ((status=Set_VI_Control(pwl_delay_values,channel,setting,&point_found,
-		                           &relay_range,&dummy,&UseNegData,&entry,&word_out,&actual_pol,NULL))) {
+		if (status=Set_VI_Control(parameter,channel,setting)) {
 			return status;
 		}
 	}
 
 	if (check_possible_only) {
-		if (point_found) {
+		if (pwl_struct[parameter][channel].point_found) {
 			return OK;
 		} else {
 			return CalibrationMinMaxError_delay;
@@ -950,24 +929,26 @@ int Set_Delay(int check_possible_only,int word_override,int range_override,int c
 	}
 
 
-	if (relay_range==0) {
+	if (pwl_struct[parameter][channel].range==0) {
 		cap_range_control=0;
 	} else {
-		cap_range_control = 1 << (relay_range-1);
+		cap_range_control = 1 << (pwl_struct[parameter][channel].range-1);
 	}
 
 	if (channel==0) {
-		set_dac(globals.Flash.delay_dac[channel],word_out);
+		set_dac(globals.Flash.delay_dac[channel],pwl_struct[parameter][channel].word_out);
 		set_shiftreg_bits(SR_2, POS_8, SEVEN_BITS, cap_range_control);
 	} else if ((channel==1) && (globals.Flash.min_delay[channel] >= 0.0)) {
-		control_pcb107(globals.Flash.I2C_port_for_CH2_delay,globals.Flash.delay_dac[channel],word_out,relay_range);
+		control_pcb107(globals.Flash.I2C_port_for_CH2_delay,globals.Flash.delay_dac[channel],
+			pwl_struct[parameter][channel].word_out,
+			pwl_struct[parameter][channel].range);
 	} else if ((channel==1) && (globals.Flash.min_delay[channel] < 0.0)) {
 		// for obscure AVP-2CHX units, where trigger PW controls the delay of CH2
-		set_dac(4,word_out);
+		set_dac(4,pwl_struct[parameter][channel].word_out);
 		set_shiftreg_bits(SR_3, POS_0, SEVEN_BITS, cap_range_control);
 	}
 
-	g_print_debug("chan %d, delay %e nominal, %e actual, range %d, word %d\n", channel, set_delay, setting, relay_range, word_out);
+	debug_new_parameter (channel, parameter, requested_delay);
 
 	globals.ChannelState[channel].delay=set_delay;
 	Set_Update_Chans();
@@ -1711,17 +1692,13 @@ int Set_Update_Chans(void)
 
 int Set_Amp_Calib(int channel,float meas_ampl)
 {
+	const int parameter = pwl_ampl_values;
 	float change_ratio;
 	int i,status;
-	int point_found,relay_range,UseNegData,entry,word_out,actual_pol,atten_range;
 	int eprom_loc;
 
 	/* use for all channels */
 
-	/* get current range and polarity settings */
-	Set_VI_Control(pwl_ampl_values,channel,globals.ChannelState[channel].amplitude,&point_found,
-	               &relay_range,&atten_range,&UseNegData,&entry,&word_out,&actual_pol,NULL);
-
 	if (fabs(globals.ChannelState[channel].amplitude)<globals.Flash.ampl_zero_equiv[channel]) {
 		return NeedNonZeroAmpl;
 	}
@@ -1733,9 +1710,7 @@ int Set_Amp_Calib(int channel,float meas_ampl)
 	}
 
 	for (i=0; i<std_range_size; ++i)
-		globals.Flash.ampl_pwl[channel][relay_range][UseNegData][i]=
-		        globals.Flash.ampl_pwl[channel][relay_range][UseNegData][i]*change_ratio;
-
+		globals.Flash.ampl_pwl[channel][pwl_struct[parameter][channel].range][pwl_struct[parameter][channel].use_neg_data][i] *= change_ratio;
 
 	/* see if new data prevents min/max from being obtained */
 	status=Check_MinMax_Cal(channel,pwl_ampl_values);
@@ -1743,8 +1718,7 @@ int Set_Amp_Calib(int channel,float meas_ampl)
 	if (status) {
 		/* revert to original calibration */
 		for (i=0; i<std_range_size; ++i)
-			globals.Flash.ampl_pwl[channel][relay_range][UseNegData][i]=
-			        globals.Flash.ampl_pwl[channel][relay_range][UseNegData][i]/change_ratio;
+			globals.Flash.ampl_pwl[channel][pwl_struct[parameter][channel].range][pwl_struct[parameter][channel].use_neg_data][i] /= change_ratio;
 	}
 
 	eprom_loc = (char *) &(globals.Flash.ampl_pwl) - (char *) &(globals.Flash.flash_start);
@@ -1756,15 +1730,13 @@ int Set_Amp_Calib(int channel,float meas_ampl)
 
 int Set_Mon_Calib(int channel,float meas_ampl)
 {
+	const int parameter = pwl_ampl_values;
+
 	float change_ratio;
-	int point_found,relay_range,UseNegData,entry,word_out,actual_pol,eprom_loc,atten_range;
+	int eprom_loc, UseNegData;
 
 	/* use for all channels */
 
-	/* get current range and polarity settings */
-	Set_VI_Control(pwl_ampl_values,channel,globals.ChannelState[channel].amplitude,&point_found,
-	               &relay_range,&atten_range,&UseNegData,&entry,&word_out,&actual_pol,NULL);
-
 	if (fabs(globals.ChannelState[channel].Curr_Mon_value)< (5.0 * globals.Flash.monitor_step[channel])) {
 		return NeedNonZeroAmpl;
 	}
@@ -1781,7 +1753,7 @@ int Set_Mon_Calib(int channel,float meas_ampl)
 		return CalibrationPercentError;
 	}
 
-	globals.Flash.mon_vi_ratio[channel][relay_range][UseNegData]=globals.Flash.mon_vi_ratio[channel][relay_range][UseNegData]/change_ratio;
+	globals.Flash.mon_vi_ratio[channel][pwl_struct[parameter][channel].range][UseNegData] /= change_ratio;
 
 	eprom_loc = (char *) &(globals.Flash.mon_vi_ratio) - (char *) &(globals.Flash.flash_start);
 	writeUserBlock(&globals.Flash, eprom_loc, sizeof(globals.Flash.mon_vi_ratio));
@@ -2728,8 +2700,7 @@ float min_possible_hw_rise_time (int channel, float use_ampl)
 }
 
 
-int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int *relay_range,int *atten_range,
-                   int *UseNegData,int *entry,int *word_out,int *actual_pol,int *word_out_aux)
+int Set_VI_Control(int parameter,int channel,float new_ampl)
 {
 	float use_ampl,tweaked_use_ampl;
 	int i;
@@ -2758,6 +2729,24 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 
 	true_channel=channel;
 
+	pwl_struct[parameter][channel].actual_value = 0.0;
+	int new_point_found = 0;
+	pwl_struct[parameter][channel].point_found = 0;
+	int new_atten_range = 0;
+	pwl_struct[parameter][channel].atten_range = 0;
+	int new_relay_range = 0;
+	pwl_struct[parameter][channel].range = 0;
+	int new_entry = 0;
+	pwl_struct[parameter][channel].entry = 0;
+	int new_word_out = 0;
+	pwl_struct[parameter][channel].word_out = 0;
+	int new_word_out_aux = 0;
+	pwl_struct[parameter][channel].word_out_aux = 0;
+	int new_use_neg_data = 0;
+	pwl_struct[parameter][channel].use_neg_data = 0;
+	int new_actual_pol = 0;
+	pwl_struct[parameter][channel].actual_pol = 0;
+
 	top_range_only=0;
 	starting_range=0;
 	max_points=std_range_size;
@@ -2779,14 +2768,10 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 		pwl_dacval_aux=&globals.Flash.distort_dacval[0][0][0][0];
 		pwl=&globals.Flash.ampl_pwl[0][0][0][0];
 		if (new_ampl<0.0) {
-			*actual_pol=1;
-			*UseNegData=1;
-		} else {
-			*actual_pol=0;
-			*UseNegData=0;
-		}
-		if (globals.Flash.use_pos_ampl_data_only[channel] && new_ampl<0.0) {
-			*UseNegData=0;
+			new_actual_pol=1;
+			if (!globals.Flash.use_pos_ampl_data_only[channel]) {
+				new_use_neg_data=1;
+			}
 		}
 		use_ampl=fabs(new_ampl);
 
@@ -2799,7 +2784,7 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 
 		if ( globals.Flash.switchable_load[channel] &&
 		                (globals.ChannelState[channel].load_type>globals.Flash.low_load_type[channel]) &&
-		                globals.Flash.ampl_dacval[channel][3][*actual_pol][1] > 0) {
+		                globals.Flash.ampl_dacval[channel][3][new_actual_pol][1] > 0) {
 			starting_range=3;
 			top_range_only=0;
 		}
@@ -2845,7 +2830,6 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 		max_ranges=os_ranges;
 		pwl_dacval=&globals.Flash.os_dacval[0][0][0][0];
 		pwl=&globals.Flash.os_pwl[0][0][0][0];
-		*UseNegData=0;
 		use_ampl=new_ampl;
 		break;
 	case pwl_pw_values:
@@ -2853,7 +2837,6 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 		max_ranges=timing_ranges;
 		pwl_dacval=&globals.Flash.pw_dacval[0][0][0][0];
 		pwl=&globals.Flash.pw_pwl[0][0][0][0];
-		*UseNegData=0;
 		use_ampl=new_ampl;
 
 		/* increase PW if required to compensate for series output diode turn-on time */
@@ -2909,7 +2892,6 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 		max_ranges=timing_ranges;
 		pwl_dacval=&globals.Flash.delay_dacval[0][0][0][0];
 		pwl=&globals.Flash.delay_pwl[0][0][0][0];
-		*UseNegData=0;
 		use_ampl=new_ampl;
 
 		// may be overridden below, if volt_ctrl_delay and words are increasing in value
@@ -2921,7 +2903,6 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 		max_ranges=timing_ranges;
 		pwl_dacval=&globals.Flash.period_dacval[0][0][0][0];
 		pwl=&globals.Flash.period_pwl[0][0][0][0];
-		*UseNegData=0;
 		use_ampl=new_ampl;
 		reciprocal_relationship=YES;
 		break;
@@ -2930,7 +2911,6 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 		max_ranges=timing_ranges;
 		pwl_dacval=&globals.Flash.burst_dacval[0][0][0][0];
 		pwl=&globals.Flash.burst_pwl[0][0][0][0];
-		*UseNegData=0;
 		use_ampl=new_ampl;
 		reciprocal_relationship=YES;
 		break;
@@ -2940,9 +2920,9 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 		pwl_dacval=&globals.Flash.rise_time_dacval[0][0][0][0];
 		pwl=&globals.Flash.rise_time_pwl[0][0][0][0];
 		if (globals.ChannelState[channel].amplitude<0.0) {
-			*actual_pol=*UseNegData=1;
+			new_actual_pol=new_use_neg_data=1;
 		} else {
-			*actual_pol=*UseNegData=0;
+			new_actual_pol=new_use_neg_data=0;
 		}
 		use_ampl=new_ampl;
 		reciprocal_relationship=NO;
@@ -2952,7 +2932,6 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 		max_ranges=timing_ranges;
 		pwl_dacval=&globals.Flash.slew_dacval[0][0][0][0];
 		pwl=&globals.Flash.slew_pwl[0][0][0][0];
-		*UseNegData=0;
 		use_ampl=new_ampl;
 		reciprocal_relationship=NO;
 		top_range_only=YES; /* higher drive voltage = lower ripple in slew */
@@ -2960,18 +2939,17 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 	}
 
 
-
 	/* if top_range_only=false, the first match (i.e. in the lowest range) is used. */
 	/* if top_range_only=true, the last match (i.e. in the highest range) is used. */
 
-	*point_found=*relay_range=*entry=0;
-	*word_out=-1;
+	new_entry=0;
+	new_word_out=-1;
 
 	float use_atten = 1.0;
 
-	for (*atten_range = max_attens; (*atten_range >= -1) && !(*point_found);) {
+	for (new_atten_range = max_attens; (new_atten_range >= -1) && !new_point_found; ) {
 
-		(*atten_range)--;
+		new_atten_range--;
 
 		float max1 = fabs(globals.Flash.min_ampl[channel]);
 		float max2 = fabs(globals.Flash.max_ampl[channel]);
@@ -2979,19 +2957,19 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 			max1 = max2;
 		}
 
-		if (*atten_range == -1) {
+		if (new_atten_range == -1) {
 			// no valid attenuators
 			use_atten = 1.0;
 		} else {
 
 			if (parameter != pwl_ampl_values) {
 				continue;
-			} else if (globals.Flash.attenuators[channel][*atten_range] == 0.0) {
+			} else if (globals.Flash.attenuators[channel][new_atten_range] == 0.0) {
 				continue;
 			} else if (globals.Flags.attenuators_enabled == 0) {
 				continue;
 			} else {
-				use_atten = globals.Flash.attenuators[channel][*atten_range];
+				use_atten = globals.Flash.attenuators[channel][new_atten_range];
 			}
 
 			// Limit max voltage in attenuator mode to 93% of full maximum,
@@ -3002,7 +2980,7 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 			}
 		}
 
-		for (range_i=starting_range; (range_i<max_ranges) && (!*point_found || top_range_only); ++range_i) {	/* use non-all-zero ranges */
+		for (range_i=starting_range; (range_i<max_ranges) && (!new_point_found || top_range_only); ++range_i) {	/* use non-all-zero ranges */
 			/* apply pw ampl/pol tweaks */
 			if (parameter == pwl_pw_values) {
 				// tweak pw shifts
@@ -3033,10 +3011,10 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 				tweaked_use_ampl = use_ampl;
 			}
 
-			for (entry_i=0; (entry_i<max_points-1) && (!*point_found || top_range_only); ++entry_i) {
+			for (entry_i=0; (entry_i<max_points-1) && (!new_point_found || top_range_only); ++entry_i) {
 				index=true_channel*max_ranges*max_polarity*max_points
 				      +(range_i)*max_polarity*max_points
-				      +(*UseNegData)*max_points
+				      +(new_use_neg_data)*max_points
 				      +(entry_i);
 
 				// we copy these floats out into variables because anything that touches
@@ -3053,7 +3031,7 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 				                        (decreasing_values_allowed && (tweaked_use_ampl<=pwlamp1) &&	(tweaked_use_ampl>=pwlamp2))  /* for OS only */
 				                )
 				   ) {
-					*point_found=1;
+					new_point_found=1;
 
 					if ((parameter==pwl_ampl_values) && globals.Flash.ampl_os_ranges_related[channel]) {
 						for (i=0; i<std_range_size; i++) {
@@ -3065,26 +3043,26 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 							}
 						}
 						if ((globals.ChannelState[channel].offset<min_os_in_range) || (globals.ChannelState[channel].offset>max_os_in_range)) {
-							*point_found=0;	/* try higher range if can't satisfy os and ampl both in this range */
+							new_point_found=0;	/* try higher range if can't satisfy os and ampl both in this range */
 						}
 					}
 
 					if ((parameter==pwl_os_values) && globals.Flash.ampl_os_ranges_related[channel]) {
 						for (i=0; i<std_range_size; i++) {
-							if (max_ampl_in_range<globals.Flash.ampl_pwl[channel][range_i][*UseNegData][i]) {
-								max_ampl_in_range=globals.Flash.ampl_pwl[channel][range_i][*UseNegData][i];
+							if (max_ampl_in_range<globals.Flash.ampl_pwl[channel][range_i][new_use_neg_data][i]) {
+								max_ampl_in_range=globals.Flash.ampl_pwl[channel][range_i][new_use_neg_data][i];
 							}
-							if (min_ampl_in_range>globals.Flash.ampl_pwl[channel][range_i][*UseNegData][i]) {
-								min_ampl_in_range=globals.Flash.ampl_pwl[channel][range_i][*UseNegData][i];
+							if (min_ampl_in_range>globals.Flash.ampl_pwl[channel][range_i][new_use_neg_data][i]) {
+								min_ampl_in_range=globals.Flash.ampl_pwl[channel][range_i][new_use_neg_data][i];
 							}
 						}
 						if ((fabs(globals.ChannelState[channel].amplitude)<min_ampl_in_range) || (fabs(globals.ChannelState[channel].amplitude)>max_ampl_in_range)) {
-							*point_found=0;	/* try higher range if can't satisfy os and ampl both in this range */
+							new_point_found=0;	/* try higher range if can't satisfy os and ampl both in this range */
 						}
 					}
 
-					*relay_range=range_i;
-					*entry=entry_i;
+					new_relay_range=range_i;
+					new_entry=entry_i;
 
 					/* check for linear voltage-controlled PW */
 					if (		(parameter==pwl_pw_values)
@@ -3104,11 +3082,11 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 					// Normally just the first range is voltage-controlled.
 
 					if (reciprocal_relationship) {
-						*word_out = inverse_interpolation (pwl_dacval[index], pwl_dacval[index+1], pwlamp1, pwlamp2, tweaked_use_ampl);
+						new_word_out = inverse_interpolation (pwl_dacval[index], pwl_dacval[index+1], pwlamp1, pwlamp2, tweaked_use_ampl);
 					} else {
-						*word_out = linear_interpolation (pwl_dacval[index], pwl_dacval[index+1], pwlamp1, pwlamp2, tweaked_use_ampl);
-						if (pwl_dacval_aux && word_out_aux) {
-							*word_out_aux = linear_interpolation (pwl_dacval_aux[index], pwl_dacval_aux[index+1], pwlamp1, pwlamp2, tweaked_use_ampl);
+						new_word_out = linear_interpolation (pwl_dacval[index], pwl_dacval[index+1], pwlamp1, pwlamp2, tweaked_use_ampl);
+						if (pwl_dacval_aux) {
+							new_word_out_aux = linear_interpolation (pwl_dacval_aux[index], pwl_dacval_aux[index+1], pwlamp1, pwlamp2, tweaked_use_ampl);
 						}
 					}
 				}
@@ -3121,8 +3099,8 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 	/* because the reciprocal relationship allows an asymptotic extension to infinity, */
 	/* at the expense of lower resolution */
 
-	if (*word_out<0 && reciprocal_relationship) {
-		*point_found=0;
+	if (new_word_out<0 && reciprocal_relationship) {
+		new_point_found=0;
 		use_range=-1;
 		float range_start;
 
@@ -3136,7 +3114,7 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 
 			index=true_channel*max_ranges*max_polarity*max_points
 			      +(range_i)*max_polarity*max_points
-			      +(*UseNegData)*max_points;
+			      +(new_use_neg_data)*max_points;
 
 			range_start = pwl[index];
 			if ((fabs(range_start) > smallest_allowed_number) && (range_start < tweaked_use_ampl)) {
@@ -3148,43 +3126,55 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int
 			return NoHardwareRangeFoundError;
 		}
 
-		for (entry_i=max_points-2; (entry_i>=0) && (!*point_found); --entry_i) {
+		for (entry_i=max_points-2; (entry_i>=0) && (!new_point_found); --entry_i) {
 			index=true_channel*max_ranges*max_polarity*max_points
 			      +(use_range)*max_polarity*max_points
-			      +(*UseNegData)*max_points
+			      +(new_use_neg_data)*max_points
 			      +(entry_i);
 
 			/* find the last two non-zero entries, and extrapolate from them */
 			if (		(fabs(pwl[index])>smallest_allowed_number)
 			                && (fabs(pwl[index+1])>smallest_allowed_number)
 			                && (fabs(pwl[index]-pwl[index+1])>smallest_allowed_number)	) {
-				*point_found=1;
-				*relay_range=use_range;
-				*entry=entry_i;
+				new_point_found=1;
+				new_relay_range=use_range;
+				new_entry=entry_i;
 
-				*word_out = inverse_interpolation (pwl_dacval[index], pwl_dacval[index+1], pwl[index], pwl[index+1], tweaked_use_ampl);
+				new_word_out = inverse_interpolation (pwl_dacval[index], pwl_dacval[index+1], pwl[index], pwl[index+1], tweaked_use_ampl);
 			}
 		}
 	}
 
-	if (*word_out<0) {
-		*word_out=0;
+	if (new_word_out<0) {
+		new_word_out=0;
 		return HardwareWordError;
 	}
 
 	/* check for 12 or 13 bit overflow */
-	if (*word_out>dac_max) {
-		*word_out=dac_max;	/* just to prevent wandering bits */
+	if (new_word_out>dac_max) {
+		new_word_out=dac_max;	/* just to prevent wandering bits */
 		return HardwareWordError;
 	}
 
+	if (new_point_found) {
+		pwl_struct[parameter][channel].point_found = new_point_found;
+		pwl_struct[parameter][channel].actual_value = tweaked_use_ampl;
+		pwl_struct[parameter][channel].atten_range = new_atten_range;
+		pwl_struct[parameter][channel].range = new_relay_range;
+		pwl_struct[parameter][channel].entry = new_entry;
+		pwl_struct[parameter][channel].word_out = new_word_out;
+		pwl_struct[parameter][channel].word_out_aux = new_word_out_aux;
+		pwl_struct[parameter][channel].use_neg_data = new_use_neg_data;
+		pwl_struct[parameter][channel].actual_pol = new_actual_pol;
+	}
+
 	return OK;
 }
 
 
 int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
 {
-	int point_found,range,polarity,entry,word_out,total,atten_range;
+	int range,polarity,entry,word_out,total;
 	int i;
 	float max_in_range;
 	float least_integrated_error,integrated_error;
@@ -3217,6 +3207,14 @@ int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
 
 	abs_cal_point=cal_point;
 
+	// current values
+	range = pwl_struct[parameter][channel].range;
+	polarity = pwl_struct[parameter][channel].use_neg_data;
+	entry = pwl_struct[parameter][channel].entry;
+	word_out = pwl_struct[parameter][channel].word_out;
+	actual_pol = pwl_struct[parameter][channel].actual_pol;
+
+
 	switch (parameter) {
 	case (pwl_ampl_values):
 		max_polarity=ampl_polarities;
@@ -3229,8 +3227,6 @@ int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
 		size_of_x_short2=sizeof(globals.Flash.distort_dacval);
 		size_of_y_float1=sizeof(globals.Flash.ampl_pwl);
 
-		Set_VI_Control(pwl_ampl_values,channel,globals.ChannelState[channel].amplitude,&point_found,
-		               &range,&atten_range,&polarity,&entry,&word_out,&actual_pol,NULL);
 		old_val=globals.ChannelState[channel].amplitude;
 		abs_cal_point=fabs(cal_point);	/* ampl data is positive always */
 
@@ -3248,10 +3244,7 @@ int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
 		pointer_y_float1=&globals.Flash.os_pwl[0][0][0][0];
 		size_of_x_short1=sizeof(globals.Flash.os_dacval);
 		size_of_y_float1=sizeof(globals.Flash.os_pwl);
-
 		old_val=globals.ChannelState[channel].offset;
-		Set_VI_Control(pwl_os_values,channel,old_val,&point_found,
-		               &range,&atten_range,&polarity,&entry,&word_out,&actual_pol,NULL);
 		break;
 	case pwl_pw_values:
 		max_polarity=timing_polarities;
@@ -3261,8 +3254,6 @@ int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
 		size_of_x_short1=sizeof(globals.Flash.pw_dacval);
 		size_of_y_float1=sizeof(globals.Flash.pw_pwl);
 		old_val=globals.ChannelState[channel].pw;
-		Set_VI_Control(pwl_pw_values,channel,old_val,&point_found,
-		               &range,&atten_range,&polarity,&entry,&word_out,&actual_pol,NULL);
 		break;
 	case pwl_delay_values:
 		max_polarity=timing_polarities;
@@ -3272,8 +3263,6 @@ int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
 		size_of_x_short1=sizeof(globals.Flash.delay_dacval);
 		size_of_y_float1=sizeof(globals.Flash.delay_pwl);
 		old_val=globals.ChannelState[channel].delay;
-		Set_VI_Control(pwl_delay_values,channel,old_val,&point_found,
-		               &range,&atten_range,&polarity,&entry,&word_out,&actual_pol,NULL);
 		break;
 	case pwl_period_values:
 		max_polarity=timing_polarities;
@@ -3283,8 +3272,6 @@ int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
 		size_of_x_short1=sizeof(globals.Flash.period_dacval);
 		size_of_y_float1=sizeof(globals.Flash.period_pwl);
 		old_val=1.0/globals.ChannelState[channel].frequency;
-		Set_VI_Control(pwl_period_values,channel,old_val,&point_found,
-		               &range,&atten_range,&polarity,&entry,&word_out,&actual_pol,NULL);
 		break;
 	case pwl_burst_values:
 		max_polarity=timing_polarities;
@@ -3294,8 +3281,6 @@ int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
 		size_of_x_short1=sizeof(globals.Flash.burst_dacval);
 		size_of_y_float1=sizeof(globals.Flash.burst_pwl);
 		old_val=globals.ChannelState[channel].burst_time;
-		Set_VI_Control(pwl_burst_values,channel,old_val,&point_found,
-		               &range,&atten_range,&polarity,&entry,&word_out,&actual_pol,NULL);
 		break;
 	case pwl_rise_time_values:
 		max_polarity=ampl_polarities;
@@ -3305,8 +3290,6 @@ int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
 		size_of_x_short1=sizeof(globals.Flash.rise_time_dacval);
 		size_of_y_float1=sizeof(globals.Flash.rise_time_pwl);
 		old_val=globals.ChannelState[channel].rise_time;
-		Set_VI_Control(pwl_rise_time_values,channel,old_val,&point_found,
-		               &range,&atten_range,&polarity,&entry,&word_out,&actual_pol,NULL);
 		break;
 	case pwl_slew_values:
 		max_polarity=timing_polarities;
@@ -3316,8 +3299,6 @@ int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
 		size_of_x_short1=sizeof(globals.Flash.slew_dacval);
 		size_of_y_float1=sizeof(globals.Flash.slew_pwl);
 		old_val=globals.ChannelState[channel].slew;
-		Set_VI_Control(pwl_slew_values,channel,old_val,&point_found,
-		               &range,&atten_range,&polarity,&entry,&word_out,&actual_pol,NULL);
 		break;
 
 	default:
@@ -3372,7 +3353,6 @@ int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
 	}
 
 
-
 	/* move old data over */
 	for (i=max_points-1; i>entry; i--) {
 		temp_y_float1[i+1]=temp_y_float1[i];
@@ -3429,12 +3409,13 @@ int Set_VI_Add_Cal(int parameter,int channel,float cal_point)
 		}
 	}
 
-
 	/* store new calibration data for this range */
 	for (i=0; i<max_points; i++) {
 		*(float *)(&pointer_y_float1[index+i])=temp_y_float1[i];
 		*(short *)(&pointer_x_short1[index+i])=temp_x_short1[i];
+		g_print_debug("chan %d, cal add point value %e for word %d\n", channel, temp_y_float1[i], temp_x_short1[i]);
 		if (pointer_x_short2) {
+			g_print_debug("chan %d, cal add secondary point value %d\n", channel, temp_x_short2[i]);
 			*(short *)(&pointer_x_short2[index+i])=temp_x_short2[i];
 		}
 	}
@@ -3754,10 +3735,13 @@ int Set_Burst_Count(int channel,int count,float new_burst_time)
 }
 
 
-int Set_Burst_Time(int check_possible_only,int word_override,int range_override,int channel,float new_burst_time)
+int Set_Burst_Time(int check_possible_only,int word_override,int range_override,int channel,float requested_burst_time)
 {
+	const int parameter = pwl_burst_values;
+
 	int count_word_out;
-	int point_found,relay_range,UseNegData,entry,actual_pol,word_out,dummy;
+
+	float new_burst_time = requested_burst_time;
 
 	if (globals.Flash.max_burst_count[channel]<=1) {
 		return Unrecognized;
@@ -3785,18 +3769,17 @@ int Set_Burst_Time(int check_possible_only,int word_override,int range_override,
 
 	/* find appropriate range/fine settings from piece-wise linear data in flash memory */
 	if (word_override) {
-		word_out=word_override;
-		relay_range=range_override;
+		pwl_struct[parameter][channel].word_out=word_override;
+		pwl_struct[parameter][channel].range=range_override;
 	} else {
 		int status;
-		if ((status=Set_VI_Control(pwl_burst_values,channel,new_burst_time,&point_found,
-		                           &relay_range,&dummy,&UseNegData,&entry,&word_out,&actual_pol,NULL))) {
+		if (status=Set_VI_Control(parameter,channel,new_burst_time)) {
 			return status;
 		}
 	}
 
 	if (check_possible_only) {
-		if (point_found) {
+		if (pwl_struct[parameter][channel].point_found) {
 			return OK;
 		} else {
 			return CalibrationMinMaxError_burst;
@@ -3806,7 +3789,7 @@ int Set_Burst_Time(int check_possible_only,int word_override,int range_override,
 	start_gate_override ();
 
 	/* update DAC */
-	set_dac(6,word_out);
+	set_dac(6,pwl_struct[parameter][channel].word_out);
 
 
 	/* update range and burst count */
@@ -3822,7 +3805,7 @@ int Set_Burst_Time(int check_possible_only,int word_override,int range_override,
 	I2C_Write(PCF8574+Second_PW_Port, hextext_out | 0x40 );
 
 	/* send second hextet */
-	hextext_out=	((count_word_out >> 6) & 0x07) | ((relay_range	 << 3) & 0x0038);
+	hextext_out=	((count_word_out >> 6) & 0x07) | ((pwl_struct[parameter][channel].range << 3) & 0x0038);
 
 	I2C_Write(PCF8574+Second_PW_Port, hextext_out);
 	/* load hextet */
@@ -3831,26 +3814,30 @@ int Set_Burst_Time(int check_possible_only,int word_override,int range_override,
 	/* clear the lines */
 	I2C_Write(PCF8574+Second_PW_Port,0);
 
-	if (globals.Registers.last_relay_driver_settings[2] != relay_range) {
+	if (globals.Registers.last_relay_driver_settings[2] != pwl_struct[parameter][channel].range) {
 		g_usleep (1e3 * globals.Timers.normal_relay_bounce_time_in_milliseconds);
 	}
 	stop_gate_override ();
 
-	globals.Registers.last_relay_driver_settings[2] = relay_range;
+	globals.Registers.last_relay_driver_settings[2] = pwl_struct[parameter][channel].range;
 
-	globals.ChannelState[channel].burst_time = new_burst_time;
+	debug_new_parameter (channel, parameter, requested_burst_time);
 
+	globals.ChannelState[channel].burst_time = new_burst_time;
 	Set_Update_Chans();
 
 	return OK;
 }
 
 
-int Set_rise_time(int check_possible_only,int word_override,int range_override,int channel,float new_rise_time)
+int Set_rise_time(int check_possible_only,int word_override,int range_override,int channel,float requested_rise_time)
 {
-	int point_found,relay_range,UseNegData,entry,actual_pol,word_out,dummy;
+	const int parameter = pwl_rise_time_values;
+
 	char range_control;
 
+	float new_rise_time = requested_rise_time;
+
 	if (globals.Flash.fixed_rise_time[channel]) {
 		return Unrecognized;
 	}
@@ -3892,29 +3879,28 @@ int Set_rise_time(int check_possible_only,int word_override,int range_override,i
 
 		/* find appropriate range/fine settings from piece-wise linear data in flash memory */
 		if (word_override) {
-			word_out=word_override;
-			relay_range=range_override;
+			pwl_struct[parameter][channel].word_out=word_override;
+			pwl_struct[parameter][channel].range=range_override;
 		} else {
 			int status;
-			if ((status=Set_VI_Control(pwl_rise_time_values,channel,new_rise_time,&point_found,
-						   &relay_range,&dummy,&UseNegData,&entry,&word_out,&actual_pol,NULL))) {
+			if (status=Set_VI_Control(parameter,channel,new_rise_time)) {
 				return status;
 			}
 		}
 
 		if (check_possible_only) {
-			if (point_found) {
+			if (pwl_struct[parameter][channel].point_found) {
 				return OK;
 			} else {
 				return CalibrationMinMaxError_rise;
 			}
 		}
 
-		set_dac(globals.Flash.rise_time_dac[channel],word_out);
+		set_dac(globals.Flash.rise_time_dac[channel],pwl_struct[parameter][channel].word_out);
 
 		if (!globals.Flash.pcb_203a_rise_time[channel]) {
 			/* original AVRQ PCB */
-			switch (relay_range) {
+			switch (pwl_struct[parameter][channel].range) {
 			case 0:
 				range_control = (char) 0x01;
 				break;
@@ -3940,7 +3926,7 @@ int Set_rise_time(int check_possible_only,int word_override,int range_override,i
 			}
 		} else {
 			/* PCB 203A */
-			switch (relay_range) {
+			switch (pwl_struct[parameter][channel].range) {
 			case 0:
 				range_control = (char) 0x0f;
 				break;
@@ -3986,8 +3972,9 @@ int Set_rise_time(int check_possible_only,int word_override,int range_override,i
 		globals.Registers.last_rise_time_relay_setting = range_control;
 	}
 
+	debug_new_parameter (channel, parameter, requested_rise_time);
+ 
 	globals.ChannelState[channel].rise_time = new_rise_time;
-
 	Set_Update_Chans();
 
 	return OK;
@@ -4038,12 +4025,16 @@ int Set_current_limit(int check_possible_only,int channel,float new_adj_current_
 }
 
 
-int Set_slew(int check_possible_only,int word_override,int range_override,int channel,float new_slew)
+int Set_slew(int check_possible_only,int word_override,int range_override,int channel,float requested_slew)
 {
+	const int parameter = pwl_slew_values;
+
 	int check_valid;
-	int status,point_found,relay_range,UseNegData,entry,actual_pol,word_out,dummy;
+	int status;
 	char range_control;
 
+	float new_slew = requested_slew;
+
 	if (!globals.Flash.curr_slew[channel]) {
 		return Unrecognized;
 	}
@@ -4067,26 +4058,25 @@ int Set_slew(int check_possible_only,int word_override,int range_override,int ch
 
 	/* find appropriate range/fine settings from piece-wise linear data in flash memory */
 	if (word_override) {
-		word_out=word_override;
-		relay_range=range_override;
+		pwl_struct[parameter][channel].word_out=word_override;
+		pwl_struct[parameter][channel].range=range_override;
 	} else {
-		if ((status=Set_VI_Control(pwl_slew_values,channel,new_slew,&point_found,
-		                           &relay_range,&dummy,&UseNegData,&entry,&word_out,&actual_pol,NULL))) {
+		if (status=Set_VI_Control(parameter,channel,new_slew)) {
 			return status;
 		}
 	}
 
 	if (check_possible_only) {
-		if (point_found) {
+		if (pwl_struct[parameter][channel].point_found) {
 			return OK;
 		} else {
 			return CalibrationMinMaxError_slew;
 		}
 	}
 
-	set_dac(globals.Flash.slew_dac[channel],word_out);
+	set_dac(globals.Flash.slew_dac[channel],pwl_struct[parameter][channel].word_out);
 
-	switch (relay_range) {
+	switch (pwl_struct[parameter][channel].range) {
 	case 0:
 		range_control = 0x0f;
 		break;
@@ -4107,8 +4097,9 @@ int Set_slew(int check_possible_only,int word_override,int range_override,int ch
 
 	I2C_Write(PCF8574,range_control);
 
-	globals.ChannelState[channel].slew = new_slew;
+	debug_new_parameter (channel, parameter, requested_slew);
 
+	globals.ChannelState[channel].slew = new_slew;
 	Set_Update_Chans();
 
 	return OK;
@@ -4913,7 +4904,7 @@ static void set_shiftreg_bits(int shiftreg, int start_at_bit, int numbits, int v
 	long shift_value = (value & used_bits) << start_at_bit;
 	long masked_reg = globals.Registers.shift_reg_out[shiftreg] & mask;
 
-	g_print_debug(": shiftreg %d, mask %x, start_at_bit %d, numbits %d, value %x\n", shiftreg, mask, start_at_bit, numbits, value);
+	g_print_debug(": shiftreg %d, mask %lx, start_at_bit %d, numbits %d, value %x\n", shiftreg, mask, start_at_bit, numbits, value);
 
 	if (shiftreg == SR_2) {
 		int i;
diff --git a/device-functions.h b/device-functions.h
index e3ba3a2..ade757a 100644
--- a/device-functions.h
+++ b/device-functions.h
@@ -46,8 +46,7 @@ int Set_Dly_Shr_Cal(int channel,int calibration_point_number,float cal_point);
 int Set_Cal_Nom(int channel,int calibration_point_number,int parameter, float *nom_val);
 int Set_VI_Cal_Pnt(int parameter,int channel,int calibration_point_number,float cal_point);
 int Set_VI_Del_Cal(int parameter,int channel,int calibration_point_number);
-int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int *relay_range,int *atten_range,
-                   int *UseNegData,int *entry,int *word_out,int *actual_pol,int *word_out_aux);
+int Set_VI_Control(int parameter,int channel,float new_ampl);
 int Set_VI_Add_Cal(int parameter,int channel,float cal_point);
 int Get_VI_Num_Pnts(int parameter,int channel);
 int Get_VI_Rng_Info(int parameter, int channel, int calibration_point_number, int *range,
diff --git a/globals.c b/globals.c
index 5948a79..d62b818 100644
--- a/globals.c
+++ b/globals.c
@@ -26,6 +26,9 @@ GlobalStruct globals = {
 };
 
 
+PwlStruct pwl_struct[pwl_max_types][max_channels];
+
+
 long sec_timer (void)
 {
 	return (long)time(NULL);
@@ -43,3 +46,18 @@ unsigned long long ms_timer (void)
 
 	return millisecondsSinceEpoch;
 }
+
+const char* param_name[] = { "AMPL", "OS", "PW", "DELAY", "PERIOD", "BURST", "RISE", "SLEW", "DISTORT" };
+
+void debug_new_parameter (int channel, int parameter, float requested)
+{
+	g_print_debug("chan %d, %s, requested %e, adjusted %e, polarity %d, range %d, word %d, aux %d, atten %d\n", 
+		channel, param_name[parameter], requested,
+		pwl_struct[parameter][channel].actual_value,
+		pwl_struct[parameter][channel].actual_pol,
+		pwl_struct[parameter][channel].range,
+                pwl_struct[parameter][channel].word_out,
+		pwl_struct[parameter][channel].word_out_aux,
+		pwl_struct[parameter][channel].atten_range);
+}
+
diff --git a/globals.h b/globals.h
index ca46c20..d78584a 100644
--- a/globals.h
+++ b/globals.h
@@ -145,13 +145,14 @@
 
 #define pwl_ampl_values 0
 #define pwl_os_values 1
-#define pwl_pw_values 3
-#define pwl_delay_values 4
-#define pwl_period_values 5
-#define pwl_burst_values 6
-#define pwl_rise_time_values 7
-#define pwl_slew_values 9
-#define pwl_distort_values 10
+#define pwl_pw_values 2
+#define pwl_delay_values 3
+#define pwl_period_values 4
+#define pwl_burst_values 5
+#define pwl_rise_time_values 6
+#define pwl_slew_values 7
+#define pwl_distort_values 8
+#define pwl_max_types 9
 
 #define dac_max 8191
 
@@ -293,12 +294,13 @@
 #define Submenu1_avrq 3400
 
 
-// must be equal!
+// must be equal!;
 #define Submenu_maximum_entries 10
 #define max_fixed_ampl_points 10
 
 long sec_timer (void);
 unsigned long long ms_timer (void);
+void debug_new_parameter (int channel, int parameter, float requested);
 
 
 #define max_gpib_input_length 512
@@ -340,6 +342,19 @@ typedef struct {
 } ChangeStruct;
 
 
+typedef struct {
+	int point_found;
+	int range;
+	int atten_range;
+	int entry;
+	int word_out;
+	int actual_pol;
+	int use_neg_data;
+	int word_out_aux;
+	float actual_value;
+} PwlStruct;
+
+
 typedef struct {
 	int channel;
 	int cal_type;
@@ -958,5 +973,7 @@ typedef struct {
 
 extern GlobalStruct globals;
 
+extern PwlStruct pwl_struct[pwl_max_types][max_channels]; 
+
 #endif
 
diff --git a/monitor.c b/monitor.c
index 41e5403..7321af6 100644
--- a/monitor.c
+++ b/monitor.c
@@ -157,7 +157,6 @@ int I2C_Check_Monitors(void)
 	int monitor_word;
 	float new_val, avg_val, step_size, max_dev_in_steps;
 	int channel;
-	int ampl_range,point_found,UseNegData,entry,word_out,atten_range;
 
 	int update_display;
 	int use_neg_data;
@@ -193,13 +192,9 @@ int I2C_Check_Monitors(void)
 
 		monitor_word=I2C_Get_Monitor_Word(channel);
 
-		/* determine current ampl_range */
-		Set_VI_Control(pwl_ampl_values,channel,globals.ChannelState[channel].amplitude,&point_found,
-		               &ampl_range,&atten_range,&UseNegData,&entry,&word_out,&actual_pol,NULL);
-
 		/* 5.0V is the full-scale voltage of the 12bit ADC */
 		new_val = ((((float) monitor_word)/4095.0) * 5.0)
-		                / globals.Flash.mon_vi_ratio[channel][ampl_range][use_neg_data];
+		                / globals.Flash.mon_vi_ratio[channel][pwl_struct[pwl_ampl_values][channel].range][pwl_struct[pwl_ampl_values][channel].use_neg_data];
 
 		/* averaging */
 		for (i=CURR_MON_MAX_OLD_COUNTS-1;i>0;i--) {
-- 
cgit