Beispiel #1
0
MX_EXPORT mx_status_type
mxd_handel_timer_finish_record_initialization( MX_RECORD *record )
{
	static const char fname[] =
			"mxd_handel_timer_finish_record_initialization()";

	MX_TIMER *timer;
	MX_HANDEL_TIMER *handel_timer;
	MX_RECORD *handel_record;
	const char *handel_driver_name;

	if ( record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
		"MX_RECORD pointer passed was NULL." );
	}

	timer = (MX_TIMER *) record->record_class_struct;

	if ( timer == (MX_TIMER *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"MX_TIMER pointer for record '%s' is NULL.",
			record->name );
	}

	timer->mode = MXCM_PRESET_MODE;

	handel_timer = (MX_HANDEL_TIMER *) record->record_type_struct;

	if ( handel_timer == (MX_HANDEL_TIMER *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"MX_HANDEL_TIMER pointer for record '%s' is NULL.",
			record->name );
	}

	handel_record = handel_timer->handel_record;

	if ( handel_record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"The handel_record pointer for record '%s' is NULL.",
			record->name );
	}

	handel_driver_name = mx_get_driver_name( handel_record );

	if ( strcmp( handel_driver_name, "handel" ) != 0 ) {
		return mx_error( MXE_UNSUPPORTED, fname,
		"Handel timer record '%s' can only be used with a "
		"Handel record of type 'handel'.  Instead, Handel record '%s' "
		"is of type '%s'.",
			record->name, handel_record->name, handel_driver_name );
	}

	return mx_timer_finish_record_initialization( record );
}
Beispiel #2
0
static mx_status_type
mxv_spec_get_pointers( MX_VARIABLE *variable,
			MX_SPEC_PROPERTY **spec_property,
			MX_SPEC_SERVER **spec_server,
			const char *calling_fname )
{
	static const char fname[] = "mxv_spec_get_pointers()";

	MX_RECORD *spec_server_record;
	MX_SPEC_PROPERTY *spec_property_ptr;

	if ( variable == (MX_VARIABLE *) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
			"MX_VARIABLE pointer passed by '%s' was NULL.",
			calling_fname );
	}
	if ( variable->record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
"MX_RECORD pointer for MX_VARIABLE pointer passed by '%s' was NULL.",
			calling_fname );
	}

	spec_property_ptr = (MX_SPEC_PROPERTY *)
				variable->record->record_type_struct;

	if ( spec_property != (MX_SPEC_PROPERTY **) NULL ) {
		*spec_property = spec_property_ptr;
	}

	spec_server_record = spec_property_ptr->spec_server_record;

	if ( spec_server_record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
	"spec_server_record pointer for record '%s' passed by '%s' is NULL.",
			variable->record->name, calling_fname );
	}

	if ( spec_server_record->mx_type != MXN_SPEC_SERVER ) {
		return mx_error( MXE_TYPE_MISMATCH, fname,
"spec_server_record '%s' for SPEC variable '%s' is not a SPEC server.  "
"Instead, it is a '%s' record.",
			spec_server_record->name, variable->record->name,
			mx_get_driver_name( spec_server_record ) );
	}

	if ( spec_server != (MX_SPEC_SERVER **) NULL ) {
		*spec_server = (MX_SPEC_SERVER *)
				spec_server_record->record_type_struct;
	}

	return MX_SUCCESSFUL_RESULT;
}
Beispiel #3
0
MX_EXPORT mx_status_type
mxd_icplus_get_offset( MX_AMPLIFIER *amplifier )
{
	static const char fname[] = "mxd_icplus_get_offset()";

	MX_ICPLUS *icplus;
	char command[40];
	char response[40];
	int num_items, offset_percentage;
	mx_status_type mx_status;

	icplus = NULL;

	if ( amplifier == ( MX_AMPLIFIER *) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
		"The MX_AMPLIFIER pointer passed is NULL." );
	}

	mx_status = mxd_icplus_get_pointers( amplifier->record,
						NULL, &icplus, fname );

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	snprintf( command, sizeof(command),
			":CONF%ld:CURR:OFFS?", icplus->address );

	mx_status = mxd_icplus_command( icplus, command,
					response, sizeof response,
					MXD_ICPLUS_DEBUG );

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	num_items = sscanf( response, "%d", &offset_percentage );

	if ( num_items != 1 ) {
		return mx_error( MXE_DEVICE_IO_ERROR, fname,
		"Unrecognizable response to a Get Input Offset command '%s' "
		"by %s '%s'.  Response = '%s'.",
			command, mx_get_driver_name( icplus->record ),
			amplifier->record->name, response );
	}

	amplifier->offset = 0.1 * (double) offset_percentage;

	return MX_SUCCESSFUL_RESULT;
}
Beispiel #4
0
static mx_status_type
mxd_itc503_aoutput_get_pointers( MX_ANALOG_OUTPUT *aoutput,
				MX_ITC503_AOUTPUT **itc503_aoutput,
				MX_ITC503 **itc503,
				MX_ISOBUS **isobus,
				const char *calling_fname )
{
	static const char fname[] = "mxd_itc503_aoutput_get_pointers()";

	MX_ITC503_AOUTPUT *itc503_aoutput_ptr;
	MX_RECORD *controller_record, *isobus_record;
	MX_ITC503 *itc503_ptr;

	if ( aoutput == (MX_ANALOG_OUTPUT *) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
		"The MX_ANALOG_OUTPUT pointer passed was NULL." );
	}

	if ( aoutput->record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
    "The MX_RECORD pointer for the MX_ANALOG_OUTPUT pointer passed was NULL." );
	}

	itc503_aoutput_ptr = (MX_ITC503_AOUTPUT *)
				aoutput->record->record_type_struct;

	if ( itc503_aoutput_ptr == (MX_ITC503_AOUTPUT *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"MX_ITC503_AOUTPUT pointer for analog output '%s' is NULL",
			aoutput->record->name );
	}

	if ( itc503_aoutput != (MX_ITC503_AOUTPUT **) NULL ) {
		*itc503_aoutput = itc503_aoutput_ptr;
	}

	controller_record = itc503_aoutput_ptr->controller_record;

	if ( controller_record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"controller_record pointer for analog output '%s' is NULL.",
			aoutput->record->name );
	}

	switch( controller_record->mx_type ) {
	case MXI_CTRL_ITC503:
	case MXI_CTRL_CRYOJET:
		break;
	default:
		return mx_error( MXE_TYPE_MISMATCH, fname,
		"controller_record '%s' for ITC503 control record '%s' "
		"is not an 'itc503' or a 'cryojet' record.  Instead, "
		"it is of type '%s'.",
			controller_record->name, aoutput->record->name,
			mx_get_driver_name( controller_record ) );
		break;
	}

	itc503_ptr = (MX_ITC503 *) controller_record->record_type_struct;

	if ( itc503_ptr == (MX_ITC503 *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"The MX_ITC503 pointer for ITC503 controller '%s' "
		"used by ITC503 status record '%s' is NULL.",
			controller_record->name,
			aoutput->record->name );
	}

	if ( itc503 != (MX_ITC503 **) NULL ) {
		*itc503 = itc503_ptr;
	}

	if ( isobus != (MX_ISOBUS **) NULL ) {
		isobus_record = itc503_ptr->isobus_record;

		if ( isobus_record == (MX_RECORD *) NULL ) {
			return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
			"The isobus_record pointer for %s "
			"controller record '%s' is NULL.",
				itc503_ptr->label,
				controller_record->name );
		}

		*isobus = isobus_record->record_type_struct;

		if ( (*isobus) == (MX_ISOBUS *) NULL ) {
			return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
			"The MX_ISOBUS pointer for ISOBUS record '%s' "
			"is NULL.", isobus_record->name );
		}
	}

	return MX_SUCCESSFUL_RESULT;
}
Beispiel #5
0
MX_EXPORT mx_status_type
mxi_isobus_open( MX_RECORD *record )
{
	static const char fname[] = "mxi_isobus_open()";

	MX_ISOBUS *isobus;
	MX_RECORD *interface_record;
	unsigned long isobus_flags, read_terminator;
	mx_status_type mx_status;

	if ( record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
			"MX_RECORD pointer passed is NULL.");
	}

	isobus = (MX_ISOBUS *) record->record_type_struct;

	if ( isobus == (MX_ISOBUS *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"MX_ISOBUS pointer for record '%s' is NULL.", record->name);
	}

	isobus_flags = isobus->isobus_flags;

#if MXI_ISOBUS_DEBUG
	MX_DEBUG(-2,("%s invoked for record '%s', isobus_flags = %#lx.",
		fname, record->name, isobus_flags ));
#endif

	interface_record = isobus->isobus_interface.record;

	switch( interface_record->mx_class ) {
	case MXI_RS232:
		/* Verify that the RS-232 port has the right settings. */

		if ( isobus_flags & MXF_ISOBUS_READ_TERMINATOR_IS_LINEFEED ) {
			read_terminator = MX_LF;
		} else {
			read_terminator = MX_CR;
		}

		mx_status = mx_rs232_verify_configuration( interface_record,
				9600, 8, 'N', 1, 'N', read_terminator, 0x0d );

		if ( mx_status.code != MXE_SUCCESS )
			return mx_status;

		/* Reinitialize the serial port. */

		mx_status = mx_resynchronize_record( interface_record );

		if ( mx_status.code != MXE_SUCCESS )
			return mx_status;

		mx_msleep(1000);

		/* Discard any characters waiting to be sent or received. */

		mx_status = mx_rs232_discard_unwritten_output(
					interface_record, MXI_ISOBUS_DEBUG );

		if ( mx_status.code != MXE_SUCCESS )
			return mx_status;

		mx_status = mx_rs232_discard_unread_input(
					interface_record, MXI_ISOBUS_DEBUG );

		if ( mx_status.code != MXE_SUCCESS )
			return mx_status;
		break;

	case MXI_GPIB:
		/* GPIB does not require any initialization. */

		break;
	
	default:
		return mx_error( MXE_TYPE_MISMATCH, fname,
		"Only RS-232 and GPIB interfaces are supported for "
		"ISOBUS interface '%s'.  Interface record '%s' is "
		"of unsupported type '%s'.",
			record->name, interface_record->name,
			mx_get_driver_name( interface_record ) );

		break;
	}

	return MX_SUCCESSFUL_RESULT;
}
Beispiel #6
0
static mx_status_type
mxd_smartmotor_ain_get_pointers( MX_ANALOG_INPUT *ainput,
			MX_SMARTMOTOR_AINPUT **smartmotor_ainput,
			MX_SMARTMOTOR **smartmotor,
			const char *calling_fname )
{
	static const char fname[] = "mxd_smartmotor_ain_get_pointers()";

	MX_RECORD *smartmotor_record;

	if ( ainput == (MX_ANALOG_INPUT *) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
			"MX_ANALOG_INPUT pointer passed by '%s' was NULL.",
			calling_fname );
	}
	if ( smartmotor_ainput == (MX_SMARTMOTOR_AINPUT **) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
			"MX_SMARTMOTOR_AINPUT pointer passed by '%s' was NULL.",
			calling_fname );
	}
	if ( smartmotor == (MX_SMARTMOTOR **) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
			"MX_SMARTMOTOR pointer passed by '%s' was NULL.",
			calling_fname );
	}
	if ( ainput->record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
"MX_RECORD pointer for MX_ANALOG_INPUT pointer passed by '%s' was NULL.",
			calling_fname );
	}

	*smartmotor_ainput = (MX_SMARTMOTOR_AINPUT *)
				ainput->record->record_type_struct;

	if ( *smartmotor_ainput == (MX_SMARTMOTOR_AINPUT *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
	"MX_SMARTMOTOR_AINPUT pointer for record '%s' passed by '%s' is NULL.",
			ainput->record->name, calling_fname );
	}

	smartmotor_record = (*smartmotor_ainput)->smartmotor_record;

	if ( smartmotor_record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"MX_SMARTMOTOR pointer for SMARTMOTOR analog input "
		"record '%s' passed by '%s' is NULL.",
			ainput->record->name, calling_fname );
	}

	if ( smartmotor_record->mx_type != MXT_MTR_SMARTMOTOR ) {
		return mx_error( MXE_TYPE_MISMATCH, fname,
		"smartmotor_record '%s' for SmartMotor analog input '%s' "
		"is not a SmartMotor record.  Instead, it is a '%s' record.",
			smartmotor_record->name, ainput->record->name,
			mx_get_driver_name( smartmotor_record ) );
	}

	*smartmotor = (MX_SMARTMOTOR *) smartmotor_record->record_type_struct;

	if ( *smartmotor == (MX_SMARTMOTOR *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
	"The MX_SMARTMOTOR pointer for SmartMotor record '%s' used by "
	"SmartMotor analog input record '%s' and passed by '%s' is NULL.",
			smartmotor_record->name,
			ainput->record->name,
			calling_fname );
	}

	return MX_SUCCESSFUL_RESULT;
}
Beispiel #7
0
MX_EXPORT mx_status_type
mxd_icplus_command( MX_ICPLUS *icplus,
			char *command,
			char *response,
			size_t response_buffer_length,
			int debug_flag )
{
	static const char fname[] = "mxd_icplus_command()";

	char c;
	int i, max_attempts;
	unsigned long sleep_ms, num_input_bytes_available;
	mx_status_type mx_status, mx_status2;

	if ( icplus == (MX_ICPLUS *) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
		"NULL MX_ICPLUS pointer passed." );
	}
	if ( command == NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
		"NULL command buffer pointer passed." );
	}

	if ( debug_flag ) {
		MX_DEBUG(-2,("%s: sending '%s' to '%s'",
				fname, command, icplus->record->name ));
	}

	/* Send the command string. */

	mx_status = mx_rs232_putline( icplus->rs232_record, command, NULL, 0 );

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	/* The IC PLUS always sends an ACK character to acknowledge receipt
	 * of the LF terminator for the command that we just sent.  Even if
	 * we expect no other response, we must still read and discard this
	 * ACK character.
	 */

	mx_status = mx_rs232_getchar( icplus->rs232_record, &c, MXF_232_WAIT );

	if ( mx_status.code == MXE_NOT_READY ) {
		return mx_error( MXE_NOT_READY, fname,
		"No response received from %s amplifier '%s' "
		"for command '%s'.  Are you sure it is plugged in "
		"and turned on?",
			mx_get_driver_name( icplus->record ),
			icplus->record->name, command );
	}

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	if ( c != MX_ACK ) {
		(void) mx_rs232_discard_unread_input( icplus->rs232_record,
							MXD_ICPLUS_DEBUG );

		return mx_error( MXE_DEVICE_IO_ERROR, fname,
	"Did not receive an ACK acknowledgement character from "
	"%s interface '%s' in response to the command '%s'.  "
	"Instead, saw a %#x (%c) character.",
			mx_get_driver_name( icplus->record ),
			icplus->record->name, command, c, c );
	}

	/* If we expect a response, then read it in. */

	if ( response != NULL ) {
		mx_status = mx_rs232_getline( icplus->rs232_record,
					response, response_buffer_length,
					NULL, 0 );

		if ( debug_flag & (mx_status.code == MXE_SUCCESS) ) {
			MX_DEBUG(-2,("%s: received '%s' from '%s'",
				fname, response, icplus->record->name ));
		}
	} else {
		if ( debug_flag ) {
			MX_DEBUG(-2,("%s complete.", fname));
		}
	}

	/* If the IC PLUS echoes the command line back to us, then we must
	 * throw this away.
	 */

	if ( icplus->discard_echoed_command_line ) {
		max_attempts = 100;
		sleep_ms = 1;

		for ( i = 0; i < max_attempts; i++ ) {
			mx_status2 = mx_rs232_num_input_bytes_available(
						icplus->rs232_record,
						&num_input_bytes_available );

			if ( mx_status2.code != MXE_SUCCESS )
				break;

			if ( num_input_bytes_available > 0 )
				break;

			mx_msleep( sleep_ms );
		}

		if ( i >= max_attempts ) {
			mx_status = mx_error( MXE_TIMED_OUT, fname,
				"Timed out waiting for %s record '%s' to echo "
				"the command line '%s' back to us.",
					mx_get_driver_name( icplus->record ),
					icplus->record->name, command );
		}
		(void) mx_rs232_discard_unread_input(
					icplus->rs232_record, FALSE );
	}

	return mx_status;
}
Beispiel #8
0
MX_EXPORT mx_status_type
mxd_icplus_get_gain( MX_AMPLIFIER *amplifier )
{
	static const char fname[] = "mxd_icplus_get_gain()";

	MX_ICPLUS *icplus;
	char command[40];
	char response[40];
	int num_items;
	long exponent;
	mx_status_type mx_status;

	icplus = NULL;

	if ( amplifier == ( MX_AMPLIFIER *) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
		"The MX_AMPLIFIER pointer passed is NULL." );
	}

	mx_status = mxd_icplus_get_pointers( amplifier->record,
						NULL, &icplus, fname );

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	snprintf( command, sizeof(command),
			":CONF%ld:CURR:RANG?", icplus->address );

	mx_status = mxd_icplus_command( icplus, command,
					response, sizeof response,
					MXD_ICPLUS_DEBUG );

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	num_items = sscanf( response, "%ld", &(icplus->range) );

	if ( num_items != 1 ) {
		return mx_error( MXE_DEVICE_IO_ERROR, fname,
		"Unrecognizable response to a Get Input Range command '%s' "
		"by %s record '%s'.  Response = '%s'.",
			command, mx_get_driver_name( icplus->record ),
			amplifier->record->name, response );
	}

	if ( (icplus->qbpm_flags & MXF_QBPM_USE_NEW_GAINS) == 0 ) {
		/* Use power of 10 gains. */

		exponent = 11 - icplus->range;

		amplifier->gain = pow( 10.0, (double) exponent );
	} else {
		/* Use new irregular gain pattern. */

		switch( icplus->range ) {
		case 1:
			amplifier->gain = 1.4e9;
			break;
		case 2:
			amplifier->gain = 7.0e8;
			break;
		case 3:
			amplifier->gain = 3.5e8;
			break;
		case 4:
			amplifier->gain = 7.0e7;
			break;
		case 5:
			amplifier->gain = 7.0e6;
			break;
		case 6:
			amplifier->gain = 7.0e5;
			break;
		default:
			amplifier->gain = -1.0;
			break;
		}
	}

	return MX_SUCCESSFUL_RESULT;
}
Beispiel #9
0
MX_EXPORT mx_status_type
mxd_icplus_open( MX_RECORD *record )
{
	static const char fname[] = "mxd_icplus_open()";

	MX_AMPLIFIER *amplifier;
	MX_ICPLUS *icplus;
	MX_RS232 *rs232;
	char command[40];
	char response[80];
	int timed_out;
	unsigned long i, max_attempts, wait_ms, num_input_bytes_available;
	mx_status_type mx_status;

	amplifier = NULL;
	icplus = NULL;

	mx_status = mxd_icplus_get_pointers( record,
					&amplifier, &icplus, fname );

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	mx_status = mx_rs232_get_pointers( icplus->rs232_record,
						&rs232, NULL, fname );

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	MX_DEBUG( 2,("%s invoked for record '%s'.", fname, record->name));

	/* The ICPLUS driver does not use the QBPM flags. */

	if ( record->mx_type == MXT_AMP_ICPLUS ) {
		icplus->qbpm_flags = 0;
	}

	/* See if the serial port is configured correctly. */

	if( record->mx_type == MXT_AMP_ICPLUS ) {
		mx_status = mx_rs232_verify_configuration( icplus->rs232_record,
					9600, 8, 'N', 1, 'N', 0x0a, 0x0a,
					rs232->timeout );
	} else {
		mx_status = mx_rs232_verify_configuration( icplus->rs232_record,
					19200, 8, 'N', 1, 'N', 0x0a, 0x0a,
					rs232->timeout );
	}

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	/* Throw away any leftover characters. */

	mx_status = mx_rs232_discard_unwritten_output( icplus->rs232_record,
							MXD_ICPLUS_DEBUG );

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	mx_status = mx_rs232_discard_unread_input( icplus->rs232_record,
							MXD_ICPLUS_DEBUG );

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	/* If the RS-232 port does not have a timeout specified, set
	 * the timeout to 1 second.
	 */

	if ( rs232->timeout < 0.0 ) {
		rs232->timeout = 1.0;

		MX_DEBUG( 2,("%s: forcing the timeout to 1 second.", fname));
	}

	/* See if the IC PLUS is available by trying to read
	 * the input current.
	 */

	if ( icplus->record->mx_type == MXT_AMP_ICPLUS ) {
		snprintf( command, sizeof(command),
				":READ%ld:CURR?", icplus->address );
	} else {
		snprintf( command, sizeof(command),
				":READ%ld:CURR1?", icplus->address );
	}

	wait_ms = 100;
	max_attempts = 5;
	timed_out = FALSE;

	for ( i = 0; i < max_attempts; i++ ) {
		mx_status = mxd_icplus_command( icplus, command,
					response, sizeof response,
					MXD_ICPLUS_DEBUG );

		switch( mx_status.code ) {
		case MXE_SUCCESS:
			timed_out = FALSE;
			break;
		case MXE_NOT_READY:
		case MXE_TIMED_OUT:
			timed_out = TRUE;
			break;
		default:
			return mx_status;
			break;
		}

		if ( timed_out == FALSE )
			break;			/* Exit the for() loop. */

		/* Resynchronize the serial port.  This will cause
		 * the serial port to be closed and then reopened.
		 */

#if MXD_ICPLUS_DEBUG
		MX_DEBUG(-2,("%s: resynchronizing the serial port.", fname));
#endif

		mx_status = mx_resynchronize_record( icplus->rs232_record );

		if ( mx_status.code != MXE_SUCCESS )
			return mx_status;

		mx_msleep( wait_ms );
	}

	/* If there are still characters available from the RS-232 port,
	 * then the serial port is echoing back part of the transmitted
	 * command.  This means that the RS-232 cable is incorrectly
	 * wired, but we will attempt to continue anyway.
	 */

	mx_status = mx_rs232_num_input_bytes_available( icplus->rs232_record,
						&num_input_bytes_available );

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	if ( num_input_bytes_available > 0 ) {
		icplus->discard_echoed_command_line = TRUE;

		(void) mx_rs232_discard_unread_input( icplus->rs232_record,
						      	FALSE );

		mx_warning(
	"Some or all of the command string transmitted to '%s' device '%s' "
	"was echoed back to the serial port.  This means that the RS-232 "
	"cable is incorrectly wired, but we will attempt to continue by "
	"discarding the echoed characters.  However, this slows down the "
	"driver, so it would be better to fix the wiring.",
			mx_get_driver_name( icplus->record ), record->name );

	}

	/* Set the gain, offset, and peaking time. */

	mx_status = mx_amplifier_set_gain( record, amplifier->gain );

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	mx_status = mx_amplifier_set_offset( record, amplifier->offset );

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	mx_status = mx_amplifier_set_time_constant( record,
						amplifier->time_constant );

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	/* If this is a QBPM controller, set the initial averaging. */

	if ( record->mx_type == MXT_AMP_QBPM ) {
		if ( icplus->default_averaging > 100 ) {
			return mx_error( MXE_WOULD_EXCEED_LIMIT, fname,
		"The requested averaging size of %ld for record '%s' is "
		"outside the allowed range of 1 to 100.",
				icplus->default_averaging, record->name );
		} else
		if ( icplus->default_averaging >= 1 ) {
			snprintf( command, sizeof(command),
					":READ%ld:AVGCURR %ld",
					icplus->address,
					icplus->default_averaging );
		} else
		if ( icplus->default_averaging > -1 ) {
			snprintf( command, sizeof(command),
					":READ%ld:SINGLE",
					icplus->address );
		} else
		if ( icplus->default_averaging >= -100 ) {
			snprintf( command, sizeof(command),
					":READ%ld:WDWCURR %ld",
					icplus->address,
					-(icplus->default_averaging) );
		} else {
			return mx_error( MXE_WOULD_EXCEED_LIMIT, fname,
		"The requested moving average size of %ld for record '%s' is "
		"outside the allowed range of -1 to -100.",
				icplus->default_averaging, record->name );
		}

		mx_status = mxd_icplus_command( icplus, command, NULL, 0,
							MXD_ICPLUS_DEBUG );
	}

	MX_DEBUG( 2,("%s complete.", fname));

	return MX_SUCCESSFUL_RESULT;
}
Beispiel #10
0
static mx_status_type
mxd_bluice_motor_get_pointers( MX_MOTOR *motor,
			MX_BLUICE_MOTOR **bluice_motor,
			MX_BLUICE_SERVER **bluice_server,
			MX_BLUICE_FOREIGN_DEVICE **foreign_motor,
			mx_bool_type skip_foreign_device_check,
			const char *calling_fname )
{
	static const char fname[] = "mxd_bluice_motor_get_pointers()";

	MX_RECORD *bluice_motor_record;
	MX_BLUICE_MOTOR *bluice_motor_ptr;
	MX_RECORD *bluice_server_record;
	MX_BLUICE_SERVER *bluice_server_ptr;
	MX_BLUICE_FOREIGN_DEVICE *foreign_motor_ptr;
	mx_status_type mx_status;
	long mx_status_code;

	/* In this section, we do standard MX ..._get_pointers() logic. */

	if ( motor == (MX_MOTOR *) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
		"The MX_MOTOR pointer passed by '%s' was NULL.",
			calling_fname );
	}

	bluice_motor_record = motor->record;

	if ( bluice_motor_record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"The MX_RECORD pointer for the MX_MOTOR pointer %p "
		"passed was NULL.", motor );
	}

	bluice_motor_ptr = bluice_motor_record->record_type_struct;

	if ( bluice_motor_ptr == (MX_BLUICE_MOTOR *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"The MX_BLUICE_MOTOR pointer for record '%s' is NULL.",
			bluice_motor_record->name );
	}

	if ( bluice_motor != (MX_BLUICE_MOTOR **) NULL ) {
		*bluice_motor = bluice_motor_ptr;
	}

	bluice_server_record = bluice_motor_ptr->bluice_server_record;

	if ( bluice_server_record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"The 'bluice_server_record' pointer for record '%s' "
		"is NULL.", bluice_motor_record->name );
	}

	bluice_server_ptr = bluice_server_record->record_class_struct;

	if ( bluice_server_ptr == (MX_BLUICE_SERVER *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"The MX_BLUICE_SERVER pointer for Blu-Ice server "
		"record '%s' used by record '%s' is NULL.",
			bluice_server_record->name,
			bluice_motor_record->name );
	}

	if ( bluice_server != (MX_BLUICE_SERVER **) NULL ) {
		*bluice_server = bluice_server_ptr;
	}

	if ( skip_foreign_device_check ) {
		return MX_SUCCESSFUL_RESULT;
	}

	/* In this section, we check to see if the pointer to the Blu-Ice
	 * foreign device structure has been set up yet.
	 */

	if ( foreign_motor != (MX_BLUICE_FOREIGN_DEVICE **) NULL ) {
		*foreign_motor = NULL;
	}

	foreign_motor_ptr = bluice_motor_ptr->foreign_device;

	if ( foreign_motor_ptr == (MX_BLUICE_FOREIGN_DEVICE *) NULL ) {
		double timeout;

		/* If not, wait a while for the pointer to be set up. */

		switch( bluice_server_record->mx_type ) {
		case MXN_BLUICE_DCSS_SERVER:
			timeout = 5.0;
			break;
		case MXN_BLUICE_DHS_SERVER:
			timeout = 0.1;
			break;
		default:
			return mx_error( MXE_TYPE_MISMATCH, fname,
			"Blu-Ice server record '%s' should be either of type "
			"'bluice_dcss_server' or 'bluice_dhs_server'.  "
			"Instead, it is of type '%s'.",
				bluice_server_record->name,
				mx_get_driver_name( bluice_server_record ) );
		}

#if BLUICE_MOTOR_DEBUG
		MX_DEBUG(-2,("%s: About to wait for device pointer "
			"initialization of motor '%s' for function '%s'.",
			fname, bluice_motor_record->name, calling_fname));
#endif
		mx_status_code = mx_mutex_lock(
				bluice_server_ptr->foreign_data_mutex );

		if ( mx_status_code != MXE_SUCCESS ) {
			return mx_error( mx_status_code, fname,
			"An attempt to lock the foreign data mutex for "
			"Blu-ice server '%s' failed.",
				bluice_server_record->name );
		}

		mx_status = mx_bluice_wait_for_device_pointer_initialization(
					bluice_server_ptr,
					bluice_motor_ptr->bluice_name,
					MXT_BLUICE_FOREIGN_MOTOR,
					&(bluice_server_ptr->motor_array),
					&(bluice_server_ptr->num_motors),
					&foreign_motor_ptr,
					timeout );

		if ( mx_status.code != MXE_SUCCESS ) {
			mx_mutex_unlock(bluice_server_ptr->foreign_data_mutex);

			return mx_status;
		}

		foreign_motor_ptr->u.motor.mx_motor = motor;

		bluice_motor_ptr->foreign_device = foreign_motor_ptr;

		mx_mutex_unlock( bluice_server_ptr->foreign_data_mutex );

#if BLUICE_MOTOR_DEBUG
		MX_DEBUG(-2,("%s: Successfully waited for device pointer "
			"initialization of motor '%s'.",
			fname, bluice_motor_record->name));
#endif
	}

	if ( foreign_motor != (MX_BLUICE_FOREIGN_DEVICE **) NULL ) {
		*foreign_motor = foreign_motor_ptr;
	}

	return MX_SUCCESSFUL_RESULT;
}
Beispiel #11
0
MX_EXPORT mx_status_type
mxd_si9650_status_read( MX_ANALOG_INPUT *ainput )
{
	static const char fname[] = "mxd_si9650_status_read()";

	MX_SI9650_STATUS *si9650_status;
	MX_SI9650_MOTOR *si9650_motor;
	MX_RECORD *si9650_motor_record;
	MX_DRIVER *driver;
	char driver_name[ MXU_DRIVER_NAME_LENGTH+1 ];
	char command[80];
	char response[80];
	int num_items;
	double status_value;
	mx_status_type mx_status;

	/* Find and check a bunch of pointers. */

	if ( ainput == (MX_ANALOG_INPUT *) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
		"The MX_ANALOG_INPUT pointer passed was NULL." );
	}
	if ( ainput->record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
    "The MX_RECORD pointer for the MX_ANALOG_INPUT pointer passed was NULL." );
	}

	si9650_status =
		(MX_SI9650_STATUS *) ainput->record->record_type_struct;

	if ( si9650_status == (MX_SI9650_STATUS *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"MX_SI9650_STATUS pointer for analog input '%s' is NULL",
			ainput->record->name );
	}

	si9650_motor_record = si9650_status->si9650_motor_record;

	if ( si9650_motor_record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
	"si9650_motor_record pointer for analog input '%s' is NULL.",
			ainput->record->name );
	}

	if ( si9650_motor_record->mx_type != MXT_MTR_SI9650 ) {
		driver = mx_get_driver_by_type( MXT_MTR_SI9650 );

		if ( driver == (MX_DRIVER *) NULL ) {
			strlcpy( driver_name, "unknown",
					MXU_DRIVER_NAME_LENGTH );
		} else {
			strlcpy( driver_name, driver->name,
					MXU_DRIVER_NAME_LENGTH );
		}

		return mx_error( MXE_TYPE_MISMATCH, fname,
	"si9650_motor_record '%s' for SI 9650 status record '%s' "
	"is not of type '%s'.  Instead, it is of type '%s'.",
			si9650_motor_record->name,
			ainput->record->name, driver_name,
			mx_get_driver_name( si9650_motor_record ) );
	}

	si9650_motor = (MX_SI9650_MOTOR *)
				si9650_motor_record->record_type_struct;

	if ( si9650_motor == (MX_SI9650_MOTOR *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
	"The MX_SI9650_MOTOR pointer for SI 9650 motor '%s' "
	"used by SI 9650 status record '%s' is NULL.",
			si9650_motor_record->name,
			ainput->record->name );
	}

	/* Request the status of the controller. */

	switch( si9650_status->parameter_type ) {
	case MXT_SI9650_TEMPERATURE_SENSOR1:
		strlcpy( command, "T", sizeof(command) );
		break;

	case MXT_SI9650_TEMPERATURE_SENSOR2:
		strlcpy( command, "t", sizeof(command) );
		break;
	default:
		return mx_error( MXE_ILLEGAL_ARGUMENT, fname,
"Unrecognized parameter type %ld for 'si9650_status' record '%s'.  "
"The allowed values are in the range (1-2).",
			si9650_status->parameter_type,
			ainput->record->name );
	}

	mx_status = mxd_si9650_motor_command( si9650_motor, command,
						response, sizeof(response),
						SI9650_STATUS_DEBUG );

	if ( mx_status.code != MXE_SUCCESS )
		return mx_status;

	num_items = sscanf( response, "%lg", &status_value );

	if ( num_items != 1 ) {
		return mx_error( MXE_DEVICE_IO_ERROR, fname,
		"Unrecognizable response returned by SI 9650 controller '%s' "
		"to command '%s'.  Response = '%s'.",
			ainput->record->name, command, response );
	}

	ainput->raw_value.double_value = 0.1 * status_value;

	return MX_SUCCESSFUL_RESULT;
}
Beispiel #12
0
static mx_status_type
mxd_compumotor_din_get_pointers( MX_DIGITAL_INPUT *dinput,
			MX_COMPUMOTOR_DINPUT **compumotor_dinput,
			MX_COMPUMOTOR_INTERFACE **compumotor_interface,
			const char *calling_fname )
{
	static const char fname[] = "mxd_compumotor_din_get_pointers()";

	MX_RECORD *compumotor_interface_record;

	if ( dinput == (MX_DIGITAL_INPUT *) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
		"MX_DIGITAL_INPUT pointer passed by '%s' was NULL.",
			calling_fname );
	}
	if (compumotor_dinput == NULL) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
		"MX_COMPUMOTOR_DINPUT pointer passed by '%s' was NULL.",
			calling_fname );
	}
	if (compumotor_interface == NULL) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
		"MX_COMPUMOTOR_INTERFACE pointer passed by '%s' was NULL.",
			calling_fname );
	}
	if ( dinput->record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
"MX_RECORD pointer for MX_DIGITAL_INPUT pointer passed by '%s' was NULL.",
			calling_fname );
	}

	*compumotor_dinput = (MX_COMPUMOTOR_DINPUT *)
					dinput->record->record_type_struct;

	if ( *compumotor_dinput == (MX_COMPUMOTOR_DINPUT *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
	"MX_COMPUMOTOR_DINPUT pointer for record '%s' passed by '%s' is NULL.",
			dinput->record->name, calling_fname );
	}

	compumotor_interface_record
		= (*compumotor_dinput)->compumotor_interface_record;

	if ( compumotor_interface_record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
	"compumotor_interface_record pointer for Compumotor digital input "
	"record '%s' passed by '%s' is NULL.",
			dinput->record->name, calling_fname );
	}

	if ( compumotor_interface_record->mx_type != MXI_CTRL_COMPUMOTOR ) {
		return mx_error( MXE_TYPE_MISMATCH, fname,
		"compumotor_interface_record '%s' for Compumotor digital "
		"input '%s' is not a Compumotor interface record.  "
		"Instead, it is a '%s' record.",
			compumotor_interface_record->name, dinput->record->name,
			mx_get_driver_name( compumotor_interface_record ) );
	}

	*compumotor_interface = (MX_COMPUMOTOR_INTERFACE *)
			compumotor_interface_record->record_type_struct;

	if ( *compumotor_interface == (MX_COMPUMOTOR_INTERFACE *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
	"The MX_COMPUMOTOR_INTERFACE pointer for Compumotor record '%s' used "
	"by Compumotor digital input record '%s' and passed by '%s' is NULL.",
			compumotor_interface_record->name,
			dinput->record->name,
			calling_fname );
	}

	return MX_SUCCESSFUL_RESULT;
}
Beispiel #13
0
static mx_status_type
mxd_mdrive_din_get_pointers( MX_DIGITAL_INPUT *dinput,
			MX_MDRIVE_DINPUT **mdrive_dinput,
			MX_MDRIVE **mdrive,
			const char *calling_fname )
{
	static const char fname[] = "mxd_mdrive_din_get_pointers()";

	MX_RECORD *mdrive_record;

	if ( dinput == (MX_DIGITAL_INPUT *) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
			"MX_DIGITAL_INPUT pointer passed by '%s' was NULL.",
			calling_fname );
	}
	if ( mdrive_dinput == (MX_MDRIVE_DINPUT **) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
			"MX_MDRIVE_DINPUT pointer passed by '%s' was NULL.",
			calling_fname );
	}
	if ( mdrive == (MX_MDRIVE **) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
			"MX_MDRIVE pointer passed by '%s' was NULL.",
			calling_fname );
	}
	if ( dinput->record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
"MX_RECORD pointer for MX_DIGITAL_INPUT pointer passed by '%s' was NULL.",
			calling_fname );
	}

	*mdrive_dinput = (MX_MDRIVE_DINPUT *)
				dinput->record->record_type_struct;

	if ( *mdrive_dinput == (MX_MDRIVE_DINPUT *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
	"MX_MDRIVE_DINPUT pointer for record '%s' passed by '%s' is NULL.",
			dinput->record->name, calling_fname );
	}

	mdrive_record = (*mdrive_dinput)->mdrive_record;

	if ( mdrive_record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"MX_MDRIVE pointer for MDRIVE digital input "
		"record '%s' passed by '%s' is NULL.",
			dinput->record->name, calling_fname );
	}

	if ( mdrive_record->mx_type != MXT_MTR_MDRIVE ) {
		return mx_error( MXE_TYPE_MISMATCH, fname,
		"mdrive_record '%s' for MDrive digital input '%s' "
		"is not a MDrive record.  Instead, it is a '%s' record.",
			mdrive_record->name, dinput->record->name,
			mx_get_driver_name( mdrive_record ) );
	}

	*mdrive = (MX_MDRIVE *) mdrive_record->record_type_struct;

	if ( *mdrive == (MX_MDRIVE *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
	"The MX_MDRIVE pointer for MDrive record '%s' used by "
	"MDrive digital input record '%s' and passed by '%s' is NULL.",
			mdrive_record->name,
			dinput->record->name,
			calling_fname );
	}

	return MX_SUCCESSFUL_RESULT;
}
Beispiel #14
0
MX_EXPORT mx_status_type
mxd_powerpmac_simultaneous_start( long num_motor_records,
				MX_RECORD **motor_record_array,
				double *position_array,
				unsigned long flags )
{
	static const char fname[] = "mxd_powerpmac_simultaneous_start()";

	MX_RECORD *powerpmac_interface_record = NULL;
	MX_RECORD *motor_record;
	MX_MOTOR *motor;
	MX_POWERPMAC_MOTOR *powerpmac_motor = NULL;
	MX_POWERPMAC *powerpmac = NULL;
	char command_buffer[500];
	char *ptr;
	const char *driver_name;
	double raw_position;
	long i, raw_steps;
	size_t length, buffer_left;
	mx_status_type mx_status;

	if ( num_motor_records <= 0 )
		return MX_SUCCESSFUL_RESULT;

	/* Construct the move command to send to the POWERPMAC. */

	ptr = command_buffer;

	*ptr = '\0';

	for ( i = 0; i < num_motor_records; i++ ) {
		motor_record = motor_record_array[i];

		motor = (MX_MOTOR *) motor_record->record_class_struct;

		driver_name = mx_get_driver_name( motor_record );

		if ( strcmp( driver_name, "powerpmac_motor" ) != 0 ) {
			return mx_error( MXE_TYPE_MISMATCH, fname,
			"Cannot perform a simultaneous start since motors "
			"'%s' and '%s' are not the same type of motors.",
				motor_record_array[0]->name,
				motor_record->name );
		}

		powerpmac_motor = (MX_POWERPMAC_MOTOR *)
					motor_record->record_type_struct;

		if ( powerpmac_interface_record == (MX_RECORD *) NULL ) {
			powerpmac_interface_record
				= powerpmac_motor->powerpmac_record;

			powerpmac = (MX_POWERPMAC *)
				powerpmac_interface_record->record_type_struct;
		}

		/* Verify that the POWERPMAC motor records all belong
		 * to the same PowerPMAC controller.
		 */

		if ( powerpmac_interface_record
				!= powerpmac_motor->powerpmac_record )
		{
			return mx_error( MXE_UNSUPPORTED, fname,
		"Cannot perform a simultaneous start for motors '%s' and '%s' "
		"since they are controlled by different POWERPMAC interfaces, "
		"namely '%s' and '%s'.",
				motor_record_array[0]->name,
				motor_record->name,
				powerpmac_interface_record->name,
				powerpmac_motor->powerpmac_record->name );
		}

		/* Compute the new position in raw units. */

		raw_position =
			mx_divide_safely( position_array[i] - motor->offset,
						motor->scale );

		raw_steps = mx_round( raw_position );

		/* Append the part of the command referring to this motor. */

		length = strlen( command_buffer );
		buffer_left = sizeof(command_buffer) - length;
		ptr = command_buffer + length;

		snprintf( ptr, buffer_left,
		    "#%ldJ=%ld ", powerpmac_motor->motor_number, raw_steps );
	}

	if ( powerpmac_interface_record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
		"No powerpmac interface record pointer was found for "
		"record '%s'.", motor_record_array[0]->name );
	}

	/* Send the command to the POWERPMAC. */

	MX_DEBUG( 2,("%s: command = '%s'", fname, command_buffer));

	mx_status = mxi_powerpmac_command( powerpmac, command_buffer,
						NULL, 0, POWERPMAC_DEBUG );

	return mx_status;
}
Beispiel #15
0
int
motor_start_fn( int argc, char *argv[] )
{
	MX_RECORD *record;
	mx_status_type mx_status;

	if ( argc != 3 ) {
		fprintf(output,
"Usage:  start 'devicename' - starts moving or counting for 'devicename'\n"
		);
		return FAILURE;
	}

	record = mx_get_record( motor_record_list, argv[2] );

	if ( record == (MX_RECORD *) NULL ) {
		fprintf( output, "Record '%s' does not exist.\n",
			argv[2] );

		return FAILURE;
	}

	/* Find out what kind of record this is. */

	switch( record->mx_superclass ) {
	case MXR_DEVICE:
		switch( record->mx_class ) {
		case MXC_MULTICHANNEL_ANALYZER:
			mx_status = mx_mca_start( record );
			break;
		case MXC_MULTICHANNEL_SCALER:
			mx_status = mx_mcs_start( record );
			break;
		case MXC_PULSE_GENERATOR:
			mx_status = mx_pulse_generator_start( record );
			break;
		default:
			fprintf(output,
				"Start is not supported for '%s' records.\n",
				mx_get_driver_name( record ) );

			return FAILURE;
			break;
		}
		break;
	case MXR_OPERATION:
		mx_status = mx_operation_start( record );
		break;
	default:
		fprintf(output,
		"Start is only supported for device and operation records.\n");

		return FAILURE;
	}


	if ( mx_status.code == MXE_SUCCESS ) {
		return SUCCESS;
	} else {
		return FAILURE;
	}
}