MX_EXPORT mx_status_type mxd_src_mono_open( MX_RECORD *record ) { static const char fname[] = "mxd_src_mono_open()"; MX_MOTOR *motor = NULL; MX_SRC_MONO *src_mono = NULL; MX_RS232 *rs232 = NULL; mx_status_type mx_status; motor = (MX_MOTOR *) record->record_class_struct; mx_status = mxd_src_mono_get_pointers(motor, &src_mono, &rs232, fname); if ( mx_status.code != MXE_SUCCESS ) return mx_status; /* Verify the RS-232 port parameters. */ #if 0 mx_status = mx_rs232_verify_configuration( src_mono->rs232_record, 9600, 8, 'N', 1, 'N', 0x0d0a, 0x0d, rs232->timeout ); if ( mx_status.code != MXE_SUCCESS ) return mx_status; #endif /* Discard any existing bytes in the serial port. */ (void) mx_rs232_discard_unwritten_output( src_mono->rs232_record, MXD_SRC_MONO_DEBUG ); mx_status = mx_rs232_discard_unread_input( src_mono->rs232_record, MXD_SRC_MONO_DEBUG ); if ( mx_status.code != MXE_SUCCESS ) return mx_status; /* Verify that the connection is alive by asking for the * current position. */ src_mono->state = MXS_SRC_MONO_IDLE; mx_status = mxd_src_mono_get_extended_status( motor ); return mx_status; }
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; }
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, &lifier, &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; }