/* ************************************************************** */ /* * Module CM2100 * This module contains I/O functions for the Compumotor model * 2100 indexer. * * Zachary Wolf * 8/24/98 */ /* ************************************************************** */ /* INCLUDES */ #include #include #include #include #include "cm2100.h" /* ************************************************************** */ /* PRIVATE FUNCTIONS */ int cm2100_open_dev(int gpib_board_addr, int gpib_dev_addr); void cm2100_close_dev(int dev_ID); int cm2100_out(int dev_ID, char *buf); int cm2100_in(int dev_ID, char* buf); int cm2100_check_dev_open(int dev_ID); int cm2100_read_error_status(int dev_ID); void cm2100_hold_until_move_complete(int dev_ID); void cm2100_hold_until_ready_to_reply(int dev_ID); int cm2100_serial_poll(int dev_ID, int* spoll); void cm2100_message(char* msg); void cm2100_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[CM2100_MAX_NUM_DEV + 1]; static int dev_descr[CM2100_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[CM2100_MAX_CMD + 1]; static char msg[CM2100_MAX_CMD + 1]; static long int cm2100_num_steps_per_rev; /* ************************************************************** */ /* PUBLIC FUNCTIONS */ /* ************************************************************** */ /* * cm2100_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 * 8/24/98 */ void cm2100_init(int gpib_board_addr, int gpib_dev_addr, int* ID) { /* Declare variables */ int dev_ID; int err; /* Message */ cm2100_message(""); cm2100_message("Initializing the CM2100..."); /* Check input parameters */ if (gpib_board_addr < 0 || gpib_board_addr > 10) { Fmt(msg, "%s 30) { Fmt(msg, "%s CM2100_MAX_NUM_DEV) { Fmt(msg, "%s 990.) { Fmt(msg, "%s 99.) { Fmt(msg, "%s 99999999) { Fmt(msg, "%s%i", &steps_taken); /* Make sure the proper number of steps were taken */ if (steps_taken != dis_steps) { cm2100_error("The wrong number of steps were taken"); return; } /* Done */ return; } /* ************************************************************** */ /* * cm2100_start_rel_move * This function starts a move of the motor. It moves the * specified number of revolutions with the specified acceleration * and velocity. * * Input: * dev_ID, device identifier * acc, acceleration (rev/sec/sec) * vel, velocity (rev/sec) * dis, distance (rev), can be + or - * * Zachary Wolf * 8/26/98 */ void cm2100_start_rel_move(int dev_ID, double acc, double vel, double dis) { /* Declare variables */ int err; int dev_open; long int dis_steps; /* Convert distance in revolutions to distance in steps */ dis_steps = dis * cm2100_num_steps_per_rev; /* Check input parameters */ if (dev_ID < 1 || dev_ID > CM2100_MAX_NUM_DEV) { Fmt(msg, "%s 990.) { Fmt(msg, "%s 99.) { Fmt(msg, "%s 99999999) { Fmt(msg, "%s CM2100_MAX_NUM_DEV) { Fmt(msg, "%s 99999999) { Fmt(msg, "%s%i", &steps_taken); /* Make sure the proper number of steps were taken */ if (steps_taken != dis_steps) { cm2100_error("The wrong number of steps were taken"); return; } /* Done */ return; } /* ************************************************************** */ /* * cm2100_get_abs_position * This function gets the number of revolutions from zero that * the motor is currently at. * * Input: * dev_ID, device identifier * * Output: * pos, position (rev), can be + or - * * Zachary Wolf * 8/26/98 */ void cm2100_get_abs_position(int dev_ID, double* pos) { /* Declare variables */ int err; int dev_open; long int pos_steps; /* Check input parameters */ if (dev_ID < 1 || dev_ID > CM2100_MAX_NUM_DEV) { Fmt(msg, "%s%i", &pos_steps); /* Convert the position in steps to position in revolutions */ *pos = (double) pos_steps / (double) cm2100_num_steps_per_rev; /* Done */ return; } /* ************************************************************** */ /* * cm2100_zero * This function sets the indexer position counter to zero. * * Input: * dev_ID, device identifier * * Zachary Wolf * 8/25/98 */ void cm2100_zero(int dev_ID) { /* Declare variables */ int err; int dev_open; /* Check input parameters */ if (dev_ID < 1 || dev_ID > CM2100_MAX_NUM_DEV) { Fmt(msg, "%s CM2100_MAX_NUM_DEV) { Fmt(msg, "%s 10) { Fmt(msg, "%s 30) { Fmt(msg, "%s%s[t-]", buf); /* Done */ return 0; } /* ************************************************************** */ /* * cm2100_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 cm2100_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 */ } } /* ************************************************************** */ /* * cm2100_read_error_status * This function obtains 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 * 8/3/98 */ int cm2100_read_error_status(int dev_ID) { /* Declare variables */ int spoll; /* Perform a serial poll */ cm2100_serial_poll(dev_ID, &spoll); /* Check for problems */ if ((spoll & 4) == 4) { cm2100_error("Limit reached"); return -1; } if ((spoll & 128) == 128) { cm2100_error("Motor stall"); return -1; } /* Done */ return 0; } /* ************************************************************** */ /* * cm2100_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 cm2100_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; } /* ************************************************************** */ /* * cm2100_hold_until_move_complete * This function serial polls the device in a loop until the * move complete bit is set. * * Input: * dev_ID, device identifier * * Zachary Wolf * 8/26/98 */ void cm2100_hold_until_move_complete(int dev_ID) { /* Declare variables */ int spoll; enum {TRUE, FALSE} busy; /* Loop while busy */ busy = TRUE; while (busy == TRUE) { cm2100_serial_poll(dev_ID, &spoll); if ((spoll & 1) == 1) { busy = FALSE; /* Move complete */ } else { busy = TRUE; /* Still moving */ Delay(.5); } } /* Done */ return; } /* ************************************************************** */ /* * cm2100_hold_until_ready_to_reply * This function serial polls the device in a loop until the * ready to reply bit is set. * * Input: * dev_ID, device identifier * * Zachary Wolf * 8/26/98 */ void cm2100_hold_until_ready_to_reply(int dev_ID) { /* Declare variables */ int spoll; enum {TRUE, FALSE} busy; /* Loop while busy */ busy = TRUE; while (busy == TRUE) { cm2100_serial_poll(dev_ID, &spoll); if ((spoll & 8) == 8) { busy = FALSE; /* Ready to reply */ } else { busy = TRUE; /* Not ready to reply */ Delay(.1); } } /* Done */ return; } /* ************************************************************** */ /* * cm2100_message * This function handles messages about the CM2100. * * Input: * message, string to display in standard I/O * * Zachary Wolf * 8/3/98 */ void cm2100_message(char* message) { /* Print the message */ printf("%s\n", message); /* Done */ return; } /* ************************************************************** */ /* * cm2100_error * This function handles error messages for the CM2100. * * Input: * message, string to display in standard I/O * * Zachary Wolf * 8/3/98 */ void cm2100_error(char* message) { /* Declare variables */ char buf[80]; /* Notify the operator of the error */ printf("\nCM2100 ERROR: %s\n", message); Beep(); Delay(.5); Beep(); /* Terminate the program if the operator desires */ printf("Press ENTER to continue.\nPress any key then ENTER to terminate program.\n"); fgets(buf, 80, stdin); if (buf[0] == '\n') return; else exit(0); }