User:Steven J. Koch/Notebook/Kochlab/2009/06/29/Feedback 96 Debugging/Richard Yeh stop condition C dcode

Richard Yeh's C code for the stop condition
/*	feedback0B-stop_condition.c * *	2000 Nov 12	SJK & RCY *		This file contains the definition of the function that *		checks various conditions to decide whether to exit the *		feedback loop. It's supposed to be compatible with the *		force clamp and velocity clamp programs written by SJK. * *		Feedback programs that use this function can be dropped *		into the versatile feedback program (currently under development) *		as individual feedback steps. Some other restrictions, *		not enumerated here, also apply to the programs used in *		that manner. *		 *		The conditions that we check (reference 001019 e-mail) are: * *			+ Trap position moved out of specified range *				(this is not necessarily the absolute range *				 of the instrument, which is checked separately) *			+ Trap power set out of specified range *			+ Feedback set point reached *				(process variable within some percent of process variable) *			+ Number of data points taken exceeds value *			+ Number of data points taken after set point first reached * *		Multiple conditions may be specified. When this is the case, *		a global logical OR or logical AND will be applied. * *		Through some conversions performed within the LabVIEW VIs *		that specify the feedback steps and exit conditions *		(see 'Feedback0B-Edit Feedback Step-Main.vi') these exit *		conditions cover: * *			+ Force exceeds some value (velocity clamp; position fixed) *			+ Time exceeds some value (number of data points, given loop time) *			+ Time after set point first reached exceeds some value */

/*	The 32-bit integer condition encodes the conditions *	that would cause the program to stop. It's also *	used as a status value. The bit field is arranged *	as described below: */

//	The least-significant 12 bits are more important //	bits 1-4: //	bits 5-8:	unused //	bits 9-12:	hard limits on AOD 2 //	bits 13-16:	unused //	bits 17-20:	soft limits on AOD 2 //	bits 21-24:	PID and other software-related limits
 * 1) define	CONDITIONFOOTSWITCHRELEASED			0x00000001
 * 2) define	CONDITIONDATAARRAYFULL				0x00000008
 * 1) define	CONDITIONHARDAOD2FREQHIGH			0x00000100
 * 2) define	CONDITIONHARDAOD2FREQLOW			0x00000200
 * 3) define	CONDITIONHARDAOD2VOLTHIGH			0x00000400
 * 4) define	CONDITIONHARDAOD2VOLTLOW			0x00000800
 * 1) define	CONDITIONSOFTAOD2FREQHIGH			0x00010000
 * 2) define	CONDITIONSOFTAOD2FREQLOW			0x00020000
 * 3) define	CONDITIONSOFTAOD2VOLTHIGH			0x00040000
 * 4) define	CONDITIONSOFTAOD2VOLTLOW			0x00080000
 * 1) define	CONDITIONSETPOINTREACHED			0x00100000
 * 2) define	CONDITIONNUMBEROFDATAPOINTS			0x00200000
 * 3) define	CONDITIONDATAPOINTSAFTERSETPOINT	0x00400000

//	bits 13-24: these are used in the logical AND computation
 * 1) define	BITSFORLOGICALAND					0x00FFF000

//	The next-most-significant 2 bits: error conditions //	The most significant bit: AND or OR conditions for bits 13-24?
 * 1) define	ERRORCOMPAREVALUES					0x10000000
 * 1) define	CONDITIONLOGICALAND					0x80000000

//	either MHz or volts
 * 1) define	TWEAK001	0.00001


 * 1) include "Eserrlp.h"//"E series Register Level Programming"
 * 2) include "feedback0b-stop_condition.h"

/*	compare_stop_condition_values *	2000 Nov 13	RCY *	This function first checks whether condition contains all the bits *	set in returnval. If not, then the function returns 0x0. *	If condition does contain the bits in returnval, then the function *	compares the values of a and b. *	If a < b, then the function returns 0x0. Otherwise, it returns returnval. */ __int32 compare_stop_condition_values (__int32 condition, __int32 returnval, double a, double b) { if (0x0 != (returnval & condition)) //	then we must check {		if (! (a < b))	//	then values are not in the proper order {			return returnval; }	}	return	0x0;	//	nothing to check, or values are fine, not triggering stop condition }

unsigned __int32	stop_condition_reached (	unsigned __int32	condition,		//	packed integer as described above	unsigned __int16	footswitch_dio_port,	//	packed integer selecting port to which footswitch is wired

double	hardlimit_aod2_freq_high, double	hardlimit_aod2_freq_low, double	hardlimit_aod2_volt_high, double	hardlimit_aod2_volt_low,

double	softlimit_aod2_freq_high, double	softlimit_aod2_freq_low, double	softlimit_aod2_volt_high, double	softlimit_aod2_volt_low,

double	setpoint, double	setpoint_proximity_margin,	//

__int32	*numberofdatapoints,			//	pointer because this function will modify value __int32	*numberofdatapointsaftersetpoint,	//	same reason as above

__int32	array_size, __int32	data_index,

double	aod2_freq_current_value, double	aod2_volt_current_value, double	process_variable ) {	unsigned __int32	stop_condition_return_value = 0x0;	unsigned __int32	setpoint_condition = 0x0;	unsigned __int16	treadle = 0x0;

//	//	Check the footswitch state (if desired) //		bit-wise AND selects only the specified channel //

if ( 0x0 != (CONDITIONFOOTSWITCHRELEASED & condition) ) {		treadle = footswitch_dio_port & Board_Read(DIO_Parallel_Input_Register * 2); if ( footswitch_dio_port == treadle ) {			stop_condition_return_value |= CONDITIONFOOTSWITCHRELEASED; //	exit immediately return	stop_condition_return_value; }	}

//	//	Check that we won't overwrite memory in the next iteration. //		This function expects to be passed the current data index value. //     i.e., in Labview one can wire the iteration "i" directly to data_index input //

if ( (data_index + 1) >= array_size) {		stop_condition_return_value |= CONDITIONDATAARRAYFULL; //	exit immediately return	stop_condition_return_value; }

//	//	Check the hard limits //

stop_condition_return_value |= compare_stop_condition_values (		condition,CONDITIONHARDAOD2FREQHIGH,		aod2_freq_current_value, hardlimit_aod2_freq_high ); stop_condition_return_value |= compare_stop_condition_values (		condition,CONDITIONHARDAOD2FREQLOW,		hardlimit_aod2_freq_low, aod2_freq_current_value + TWEAK001 ); stop_condition_return_value |= compare_stop_condition_values (		condition,CONDITIONHARDAOD2VOLTHIGH,		aod2_volt_current_value, hardlimit_aod2_volt_high ); stop_condition_return_value |= compare_stop_condition_values (		condition,CONDITIONHARDAOD2VOLTLOW,		hardlimit_aod2_volt_low, aod2_volt_current_value + TWEAK001 );

//	//	Check whether the AOD settings are within the correct range. //		If not, then set the corresponding bits in //		stop_condition_return_value. //

stop_condition_return_value |= compare_stop_condition_values ( condition,		CONDITIONSOFTAOD2FREQHIGH, aod2_freq_current_value, softlimit_aod2_freq_high );

stop_condition_return_value |= compare_stop_condition_values ( condition,		CONDITIONSOFTAOD2FREQLOW, softlimit_aod2_freq_low, aod2_freq_current_value + TWEAK001 );

stop_condition_return_value |= compare_stop_condition_values ( condition,		CONDITIONSOFTAOD2VOLTHIGH, aod2_volt_current_value, softlimit_aod2_volt_high );

stop_condition_return_value |= compare_stop_condition_values ( condition,		CONDITIONSOFTAOD2VOLTLOW, softlimit_aod2_volt_low, aod2_volt_current_value + TWEAK001 );

//	//	Check whether "setpoint is reached". //	This means to check whether the process variable is within //		the setpoint_proximity_margin of the setpoint //

if (0x0 != (CONDITIONSETPOINTREACHED & condition)) //	then we must check {		if ( (setpoint - setpoint_proximity_margin < process_variable) &&			 (setpoint + setpoint_proximity_margin > process_variable) ) {			stop_condition_return_value |= CONDITIONSETPOINTREACHED; }	}

//	//	Check whether the number of data points is exceeded. //	I could implement this either by a static variable //		or by adjusting the threshold.

if (0x0 != (CONDITIONNUMBEROFDATAPOINTS & condition)) //	then we must check {		--(*numberofdatapoints); if ( 0 >= *numberofdatapoints) //	then we have taken at least the originally-specified //	(*numberofdatapoints) data points {			stop_condition_return_value |= CONDITIONNUMBEROFDATAPOINTS; }	}

//	//	Check whether the number of data points is exceeded. //	I could implement this either by a static variable //		or by adjusting the threshold.

if (0x0 != (CONDITIONDATAPOINTSAFTERSETPOINT & condition)) //	then we must check {		if ( (setpoint - setpoint_proximity_margin < process_variable) &&			 (setpoint + setpoint_proximity_margin > process_variable) ) {			--(*numberofdatapointsaftersetpoint); if ( 0 >= *numberofdatapointsaftersetpoint) //	then we have taken at least the originally-specified //	(*numberofdatapointsaftersetpoint) data points on the setpoint {				stop_condition_return_value |= CONDITIONDATAPOINTSAFTERSETPOINT; }		}	}

//	//	Calculate the logical AND or OR of the specified stop conditions //		depending on the "AND" or the "OR" setting. //	if (CONDITIONLOGICALAND == (CONDITIONLOGICALAND & condition)) //	we must check whether all conditions succeeded {		//	restrict check to only those conditions specified in BITSFORLOGICALAND if ( (BITSFORLOGICALAND & condition) !=			 (BITSFORLOGICALAND & stop_condition_return_value) ) //	then not all the conditions were met {			//	unset all bits contained in BITSFORLOGICALAND, //	by performing a logical AND with the complement //	of BITSFORLOGICALAND stop_condition_return_value &= ~ BITSFORLOGICALAND; }		else {			stop_condition_return_value |= CONDITIONLOGICALAND; }	}

return	stop_condition_return_value; }