/* ************************************************************** */ /* * Module PM500 * This module contains I/O functions for the Newport model * PM500 controller. * * Zachary Wolf * 2/1/01 */ /* ************************************************************** */ /* INCLUDES */ #include #include #include #include #include "pm500.h" /* ************************************************************** */ /* PRIVATE FUNCTIONS */ int pm500_open_dev(int gpib_board_addr, int gpib_dev_addr); void pm500_close_dev(int dev_ID); int pm500_out(int dev_ID, char *buf); int pm500_in(int dev_ID, char* buf); int pm500_check_dev_open(int dev_ID); int pm500_check_errors(int dev_ID); int pm500_serial_poll(int dev_ID, int* spoll); void pm500_hold_until_move_complete(int dev_ID, char axis); void pm500_message(char* msg); void pm500_error(char* msg); /* ************************************************************** */ /* PRIVATE DEVICE TABLE */ /* * This table allows several devices of the same type to be * used in the system. * dev_addr, contains the GPIB addresses of opened devices * dev_descr, contains the device descriptors of opened devices * dev_count, contains the number of devices open of this type */ static int dev_addr[PM500_MAX_NUM_DEV + 1]; static int dev_descr[PM500_MAX_NUM_DEV + 1]; static int dev_count; /* ************************************************************** */ /* PRIVATE GLOBAL VARIABLES */ /* * cmd, buffer for GPIB I/O strings * msg, buffer for message strings to Standard I/O */ static char cmd[PM500_MAX_CMD + 1]; static char msg[PM500_MAX_CMD + 1]; /* ************************************************************** */ /* PUBLIC FUNCTIONS */ /* ************************************************************** */ /* * pm500_init * This function opens the device, queries for ID, and * initializes the device to a known state. * * Input: * gpib_board_addr, address of the GPIB board the device is connected to (0, 1, ...) * gpib_dev_addr, GPIB address of the device (1 to 30, 0 is reserved) * * Output: * ID, identifier for future references to the device * * Zachary Wolf * 2/1/01 */ void pm500_init(int gpib_board_addr, int gpib_dev_addr, int* ID) { /* Declare variables */ int dev_ID; int err; /* Message */ pm500_message(""); pm500_message("Initializing the PM500..."); /* Check input parameters */ if (gpib_board_addr < 0 || gpib_board_addr > 10) { Fmt(msg, "%s 30) { Fmt(msg, "%s PM500_MAX_NUM_DEV) { Fmt(msg, "%s PM500_MAX_NUM_DEV) { Fmt(msg, "%s PM500_MAX_NUM_DEV) { Fmt(msg, "%s 2.e-6) pm500_error("pm500_rel_stage_move: the stage did not move the proper amount"); /* Done */ return; } /* ************************************************************** */ /* * pm500_rel_2_stage_move * This function moves two stages a given distance relative to * their present position. The acceleration and velocity are specified. * * Input: * dev_ID, device identifier * axis1, axis 1 (A, B, X, or Y) * axis2, axis 2 (A, B, X, or Y) * acc, acceleration (m/sec/sec) * vel, velocity (m/sec) * dis, distance (m), can be + or - * * Zachary Wolf * 2/5/01 */ void pm500_rel_2_stage_move(int dev_ID, char axis1, char axis2, double acc, double vel, double dis) { /* Declare variables */ int err; int dev_open; double ini_pos1, fin_pos1; double ini_pos2, fin_pos2; /* Check input parameters */ if (dev_ID < 1 || dev_ID > PM500_MAX_NUM_DEV) { Fmt(msg, "%s 2.e-6) pm500_error("pm500_rel_stage_move: the stage did not move the proper amount"); if (fabs(fin_pos2 - ini_pos2 - dis) > 2.e-6) pm500_error("pm500_rel_stage_move: the stage did not move the proper amount"); /* Done */ return; } /* ************************************************************** */ /* * pm500_rel_2_indep_stage_move * This function moves two stages given distances relative to * their present positions. The acceleration and velocity are specified. * * Input: * dev_ID, device identifier * axis1, axis 1 (A, B, X, or Y) * axis2, axis 2 (A, B, X, or Y) * acc, acceleration (m/sec/sec) * vel, velocity (m/sec) * dis1, stage 1 distance (m), can be + or - * dis2, stage 2 distance (m), can be + or - * * Zachary Wolf * 2/5/01 */ void pm500_rel_2_indep_stage_move(int dev_ID, char axis1, char axis2, double acc, double vel, double dis1, double dis2) { /* Declare variables */ int err; int dev_open; double ini_pos1, fin_pos1; double ini_pos2, fin_pos2; /* Check input parameters */ if (dev_ID < 1 || dev_ID > PM500_MAX_NUM_DEV) { Fmt(msg, "%s 2.e-6) pm500_error("pm500_rel_stage_move: the stage did not move the proper amount"); if (fabs(fin_pos2 - ini_pos2 - dis2) > 2.e-6) pm500_error("pm500_rel_stage_move: the stage did not move the proper amount"); /* Done */ return; } /* ************************************************************** */ /* * pm500_abs_stage_move * This function moves a stage to a specified position. * The acceleration and velocity are specified. * * Input: * dev_ID, device identifier * axis, axis to move (A, B, X, or Y) * acc, acceleration (m/sec/sec) * vel, velocity (m/sec) * pos, position (m), can be + or - * * Zachary Wolf * 5/14/01 */ void pm500_abs_stage_move(int dev_ID, char axis, double acc, double vel, double pos) { /* Declare variables */ int err; int dev_open; double fin_pos; /* Check input parameters */ if (dev_ID < 1 || dev_ID > PM500_MAX_NUM_DEV) { Fmt(msg, "%s 2.e-6) pm500_error("pm500_abs_stage_move: the stage did not move the proper amount"); /* Done */ return; } /* ************************************************************** */ /* * pm500_abs_2_stage_move * This function moves two stages to a specified position. * The acceleration and velocity are specified. * * Input: * dev_ID, device identifier * axis1, axis 1 (A, B, X, or Y) * axis2, axis 2 (A, B, X, or Y) * acc, acceleration (m/sec/sec) * vel, velocity (m/sec) * pos, position (m), can be + or - * * Zachary Wolf * 5/16/01 */ void pm500_abs_2_stage_move(int dev_ID, char axis1, char axis2, double acc, double vel, double pos) { /* Declare variables */ int err; int dev_open; double fin_pos1, fin_pos2; /* Check input parameters */ if (dev_ID < 1 || dev_ID > PM500_MAX_NUM_DEV) { Fmt(msg, "%s 2.e-6) pm500_error("pm500_abs_2_stage_move: the stage did not move the proper amount"); if (fabs(fin_pos2 - pos) > 2.e-6) pm500_error("pm500_abs_2_stage_move: the stage did not move the proper amount"); /* Done */ return; } /* ************************************************************** */ /* * pm500_abs_2_indep_stage_move * This function moves two stages to their specified positions. * The acceleration and velocity are specified. * * Input: * dev_ID, device identifier * axis1, axis 1 (A, B, X, or Y) * axis2, axis 2 (A, B, X, or Y) * acc, acceleration (m/sec/sec) * vel, velocity (m/sec) * pos1, stage 1 position (m), can be + or - * pos2, stage 2 position (m), can be + or - * * Zachary Wolf * 5/16/01 */ void pm500_abs_2_indep_stage_move(int dev_ID, char axis1, char axis2, double acc, double vel, double pos1, double pos2) { /* Declare variables */ int err; int dev_open; double fin_pos1, fin_pos2; /* Check input parameters */ if (dev_ID < 1 || dev_ID > PM500_MAX_NUM_DEV) { Fmt(msg, "%s 2.e-6) pm500_error("pm500_abs_2_stage_move: the stage did not move the proper amount"); if (fabs(fin_pos2 - pos2) > 2.e-6) pm500_error("pm500_abs_2_stage_move: the stage did not move the proper amount"); /* Done */ return; } /* ************************************************************** */ /* * pm500_zero * This function zeros the specified axis. * * Input: * dev_ID, device identifier * axis, axis to move (A, B, X, or Y) * * Zachary Wolf * 5/14/01 */ void pm500_zero(int dev_ID, char axis) { /* Declare variables */ int err; int dev_open; double fin_pos; /* Check input parameters */ if (dev_ID < 1 || dev_ID > PM500_MAX_NUM_DEV) { Fmt(msg, "%s 1.) pm500_error("pm500_zero: the stage did not zero properly"); /* Done */ return; } /* ************************************************************** */ /* * pm500_get_acc * This function gets the acceleration of the specified axis. * * Input: * dev_ID, device identifier * axis, system axis (A, B, X, or Y) * * Output: * acc, stage acceleration (m/sec/sec) * * Zachary Wolf * 5/15/01 */ void pm500_get_acc(int dev_ID, char axis, double* acc) { /* Declare variables */ int err; int dev_open; int num_scan; char id, status; double acc_mm_sec_sec; /* Check input parameters */ if (dev_ID < 1 || dev_ID > PM500_MAX_NUM_DEV) { Fmt(msg, "%s%c%c%f", &id, &status, &acc_mm_sec_sec); if (num_scan != 3) pm500_error("Problem reading acceleration."); if (id != axis) pm500_error("Problem reading acceleration."); *acc = acc_mm_sec_sec / 1000.; /* Check for errors */ pm500_check_errors(dev_ID); /* Done */ return; } /* ************************************************************** */ /* * pm500_get_dcl * This function gets the deceleration of the specified axis. * * Input: * dev_ID, device identifier * axis, system axis (A, B, X, or Y) * * Output: * dcl, stage deceleration (m/sec/sec) * * Zachary Wolf * 5/15/01 */ void pm500_get_dcl(int dev_ID, char axis, double* dcl) { /* Declare variables */ int err; int dev_open; int num_scan; char id, status; double dcl_mm_sec_sec; /* Check input parameters */ if (dev_ID < 1 || dev_ID > PM500_MAX_NUM_DEV) { Fmt(msg, "%s%c%c%f", &id, &status, &dcl_mm_sec_sec); if (num_scan != 3) pm500_error("Problem reading deceleration."); if (id != axis) pm500_error("Problem reading deceleration."); *dcl = dcl_mm_sec_sec / 1000.; /* Check for errors */ pm500_check_errors(dev_ID); /* Done */ return; } /* ************************************************************** */ /* * pm500_get_vel * This function gets the velocity of the specified axis. * * Input: * dev_ID, device identifier * axis, system axis (A, B, X, or Y) * * Output: * vel, stage velocity (m/sec) * * Zachary Wolf * 5/15/01 */ void pm500_get_vel(int dev_ID, char axis, double* vel) { /* Declare variables */ int err; int dev_open; int num_scan; char id, status; double vel_mm_sec; /* Check input parameters */ if (dev_ID < 1 || dev_ID > PM500_MAX_NUM_DEV) { Fmt(msg, "%s%c%c%f", &id, &status, &vel_mm_sec); if (num_scan != 3) pm500_error("Problem reading velocity."); if (id != axis) pm500_error("Problem reading velocity."); *vel = vel_mm_sec / 1000.; /* Check for errors */ pm500_check_errors(dev_ID); /* Done */ return; } /* ************************************************************** */ /* * pm500_get_pos * This function gets the position of the specified axis. * * Input: * dev_ID, device identifier * axis, system axis (A, B, X, or Y) * * Output: * pos, stage position (m) * * Zachary Wolf * 5/15/01 */ void pm500_get_pos(int dev_ID, char axis, double* pos) { /* Declare variables */ int err; int dev_open; int num_scan; char id, status; double pos_mum; /* Check input parameters */ if (dev_ID < 1 || dev_ID > PM500_MAX_NUM_DEV) { Fmt(msg, "%s%c%c%f", &id, &status, &pos_mum); if (num_scan != 3) pm500_error("Problem reading position."); if (id != axis) pm500_error("Problem reading position."); if (status != 'D') pm500_error("Problem reading position."); *pos = pos_mum / 1.e6; /* Check for errors */ pm500_check_errors(dev_ID); /* Done */ return; } /* ************************************************************** */ /* * pm500_get_status * This function gets the status of the specified axis. * * Input: * dev_ID, device identifier * axis, system axis (A, B, X, or Y) * * Output: * status, stage status * * Zachary Wolf * 5/15/01 */ void pm500_get_status(int dev_ID, char axis, char* status) { /* Declare variables */ int err; int dev_open; int num_scan; char id; /* Check input parameters */ if (dev_ID < 1 || dev_ID > PM500_MAX_NUM_DEV) { Fmt(msg, "%s%c%c", &id, status); if (num_scan != 2) pm500_error("Problem reading status."); if (id != axis) pm500_error("Problem reading status."); /* Check for errors */ pm500_check_errors(dev_ID); /* Done */ return; } /* ************************************************************** */ /* * pm500_set_acc * This function sets the acceleration of the specified axis. * * Input: * dev_ID, device identifier * axis, system axis (A, B, X, or Y) * * Output: * acc, stage acceleration (m/sec/sec) * * Zachary Wolf * 5/15/01 */ void pm500_set_acc(int dev_ID, char axis, double acc) { /* Declare variables */ int err; int dev_open; double acc_mm_sec_sec; /* Check input parameters */ if (dev_ID < 1 || dev_ID > PM500_MAX_NUM_DEV) { Fmt(msg, "%s PM500_MAX_NUM_DEV) { Fmt(msg, "%s PM500_MAX_NUM_DEV) { Fmt(msg, "%s PM500_MAX_NUM_DEV) { Fmt(msg, "%s 10) { Fmt(msg, "%s 30) { Fmt(msg, "%s%s[t-]", buf); /* Done */ return 0; } /* ************************************************************** */ /* * pm500_check_dev_open * This function checks to see if the specified device is open. * If the device has been opened, a 1 is returned, 0 otherwise. * * Input: * dev_ID, device identifier * * Output: * status, 1 if device is open, 0 otherwise * * Zachary Wolf * 7/27/98 */ int pm500_check_dev_open(int dev_ID) { /* See if the device descriptor has a positive value */ if (dev_descr[dev_ID] > 0) { return 1; /* Open */ } else { return 0; /* Not open */ } } /* ************************************************************** */ /* * pm500_check_errors * This function checks for device errors. * The operator is alerted if there is an error. * * Input: * dev_ID, device identifier * * Output: * err, 0 if no errors, -1 otherwise * * Zachary Wolf * 5/14/01 */ int pm500_check_errors(int dev_ID) { /* Declare variables */ char err_reg[PM500_MAX_CMD + 1]; long int err_val; int num_scan; /* Get the contents of the error register */ pm500_out(dev_ID, "ESTAT ?"); pm500_in(dev_ID, err_reg); num_scan = Scan(err_reg, "%s>%c[d]%c[d]$%i", &err_val); if (num_scan != 3) pm500_error("Problem reading error register."); //printf("Error Register Contents = %s\n", err_reg); /* Debug */ /* Exit here if there are no errors */ if (err_val == 0) return 0; /* Write a message about the error */ printf("\nPM500 ERROR, error register contents = %s\n", err_reg); /* If it was an execute error, print the execute error status */ if (err_val & 4194304 == 4194304) { pm500_out(dev_ID, "EESTAT ?"); pm500_in(dev_ID, err_reg); printf("\nPM500 ERROR, execute error register contents = %s\n", err_reg); } /* See if the operator wants to continue */ pm500_error("pm500_check_errors found errors"); /* Done */ return -1; } /* ************************************************************** */ /* * pm500_serial_poll * This function performs a serial poll of the device. * * Input: * dev_ID, device identifier * * Output: * spoll, contents of the serial poll register * err, 0 if ok, -1 otherwise * * Zachary Wolf * 8/26/98 */ int pm500_serial_poll(int dev_ID, int* spoll) { /* Declare variables */ int err; char spoll_char; /* Perform the serial poll */ err = ibrsp(dev_descr[dev_ID], &spoll_char); /* Check for errors */ if (err & 0x8000) { Fmt(msg, "%s%i", spoll); /* Debug */ /* printf("%i\n", *spoll); */ /* Done */ return 0; } /* ************************************************************** */ /* * pm500_hold_until_move_complete * This function loops until all axes have stopped moving. * * Input: * dev_ID, device identifier * axis, axis to check (A, B, X, or Y) * * Zachary Wolf * 5/15/01 */ void pm500_hold_until_move_complete(int dev_ID, char axis) { /* Declare variables */ char status[PM500_MAX_CMD + 1]; enum {TRUE, FALSE} moving; /* Check input parameters */ if (dev_ID < 1 || dev_ID > PM500_MAX_NUM_DEV) { Fmt(msg, "%s