diff --git a/motorApp/ImsSrc/drvIM483PL.c b/motorApp/ImsSrc/drvIM483PL.c index c4e872e2..7510b2e3 100644 --- a/motorApp/ImsSrc/drvIM483PL.c +++ b/motorApp/ImsSrc/drvIM483PL.c @@ -3,9 +3,9 @@ FILENAME... drvIM483PL.c USAGE... Motor record driver level support for Intelligent Motion Systems, Inc. IM483(I/IE). -Version: $Revision: 1.4 $ +Version: $Revision: 1.5 $ Modified By: $Author: sluiter $ -Last Modified: $Date: 2002-03-29 21:15:24 $ +Last Modified: $Date: 2002-04-15 20:20:23 $ */ /* @@ -35,8 +35,12 @@ Last Modified: $Date: 2002-03-29 21:15:24 $ * * Modification Log: * ----------------- - * .01 07/10/00 rls copied from drvIM483SM.c - * .02 10/02/01 rls allow one retry after a communication error. + * .01 07/10/00 rls copied from drvIM483SM.c + * .02 10/02/01 rls allow one retry after a communication error. + * .03 04/15/02 rls Bug fix for limit switches. Set RA_DIRECTION in + * set_status() based on (new - old) commanded position. + * Removed support for "ASCII record separator (IS2) = /x1E" + * from send_mess(). */ /* @@ -94,7 +98,7 @@ DESIGN LIMITATIONS... /* --- Local data. --- */ int IM483PL_num_cards = 0; volatile int drvIM483PLdebug = 0; -STATIC char IM483PL_axis[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; +STATIC char IM483PL_axis[8] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'}; /* Local data required for every driver; see "motordrvComCode.h" */ #include "motordrvComCode.h" @@ -182,11 +186,6 @@ static long report(int level) card, brdptr->ident); break; - case GPIB_PORT: - printf(" IM483PL controller %d port type = GPIB, id: %s \n", - card, - brdptr->ident); - break; default: printf(" IM483PL controller %d port type = Unknown, id: %s \n", card, @@ -222,10 +221,34 @@ STATIC void query_done(int card, int axis, struct mess_node *nodeptr) } -/************************************************************** - * Parse status and position strings for a card and signal - * set_status() - ************************************************************/ +/******************************************************************************** +* * +* FUNCTION NAME: set_status * +* * +* LOGIC: * +* Initialize. * +* Send "Moving Status" query. * +* Read response. * +* IF normal response to query. * +* Set communication status to NORMAL. * +* ELSE * +* IF communication status is NORMAL. * +* Set communication status to RETRY. * +* NORMAL EXIT. * +* ELSE * +* Set communication status error. * +* ERROR EXIT. * +* ENDIF * +* ENDIF * +* * +* IF "Moving Status" indicates any motion (i.e. status != 0). * +* Clear "Done Moving" status bit. * +* ELSE * +* Set "Done Moving" status bit. * +* ENDIF * +* * +* * +********************************************************************************/ STATIC int set_status(int card, int signal) { @@ -237,6 +260,7 @@ STATIC int set_status(int card, int signal) int status; int rtn_state; double motorData; + BOOLEAN plusdir; cntrl = (struct IM483controller *) motor_state[card]->DevicePrivate; motor_info = &(motor_state[card]->motor_info[signal]); @@ -264,7 +288,7 @@ STATIC int set_status(int card, int signal) return(1); } } - + status = atoi(&buff[4]); if (status != 0) @@ -285,21 +309,42 @@ STATIC int set_status(int card, int signal) } } + /* + * Parse motor position + * Position string format: 1TP5.012,2TP1.123,3TP-100.567,... + * Skip to substring for this motor, convert to double + */ + + send_mess(card, "? Z 0", IM483PL_axis[signal]); + recv_mess(card, buff, 1); + + motorData = atof(&buff[5]); + + if (motorData == motor_info->position) + motor_info->no_motion_count++; + else + { + epicsInt32 newposition; + + newposition = NINT(motorData); + if (newposition >= motor_info->position) + motor_info->status |= RA_DIRECTION; + else + motor_info->status &= ~RA_DIRECTION; + motor_info->position = newposition; + motor_info->no_motion_count = 0; + } + + plusdir = (motor_info->status & RA_DIRECTION) ? ON : OFF; + send_mess(card, "? ] 0", IM483PL_axis[signal]); recv_mess(card, buff, 1); status = atoi(&buff[5]); - if (status == 0) - motor_info->status &= ~RA_OVERTRAVEL; - else - { + if ((plusdir == ON && (status & 1)) || (plusdir == OFF && (status & 2))) motor_info->status |= RA_OVERTRAVEL; - /* Set direction based on which LS activated. */ - if (status == L_ALIMIT) - motor_info->status |= RA_DIRECTION; - else - motor_info->status &= ~RA_DIRECTION; - } + else + motor_info->status &= ~RA_OVERTRAVEL; send_mess(card, "? ] 1", IM483PL_axis[signal]); recv_mess(card, buff, 1); @@ -318,25 +363,6 @@ STATIC int set_status(int card, int signal) motor_info->status &= ~EA_SLIP_STALL; motor_info->status &= ~EA_HOME; - /* - * Parse motor position - * Position string format: 1TP5.012,2TP1.123,3TP-100.567,... - * Skip to substring for this motor, convert to double - */ - - send_mess(card, "? Z 0", IM483PL_axis[signal]); - recv_mess(card, buff, 1); - - motorData = atof(&buff[5]); - - if (motorData == motor_info->position) - motor_info->no_motion_count++; - else - { - motor_info->position = NINT(motorData); - motor_info->no_motion_count = 0; - } - if (motor_state[card]->motor_info[signal].encoder_present == NO) motor_info->encoder_position = 0; else @@ -379,9 +405,8 @@ STATIC int set_status(int card, int signal) /*****************************************************/ STATIC int send_mess(int card, char const *com, char inchar) { - char *head, *end, local_buff[MAX_MSG_SIZE]; + char local_buff[MAX_MSG_SIZE]; struct IM483controller *cntrl; - BOOLEAN lastcmnd = OFF; int size; size = strlen(com); @@ -390,57 +415,31 @@ STATIC int send_mess(int card, char const *com, char inchar) { logMsg((char *) "drvIM483PL.c:send_mess(); message size violation.\n", 0, 0, 0, 0, 0, 0); - return (-1); + return(-1); } else if (size == 0) /* Normal exit on empty input message. */ - return (0); - + return(0); + if (!motor_state[card]) { logMsg((char *) "drvIM483PL.c:send_mess() - invalid card #%d\n", card, 0, 0, 0, 0, 0); - return (-1); + return(-1); } - head = (char *) com; - end = head + size; + /* Make a local copy of the string and add the command line terminator. */ + strcpy(local_buff, com); + strcat(local_buff, "\n"); - while (lastcmnd == OFF) - { - int size; - char *delimit; + if (inchar != (char) NULL) + local_buff[0] = inchar; /* put in axis */ - delimit = strchr(head, ';'); - if (delimit != NULL) - { - if (*(delimit + 1) == NULL) /* Test for trailing command terminator. */ - lastcmnd = ON; - size = delimit - head; - } - else - { - size = end - head; - lastcmnd = ON; - } + Debug(2, "send_mess(): message = %s\n", local_buff); - strncpy(local_buff, head, size); - head += size + 1; - local_buff[size++] = '\n'; /* Add the command line terminator. */ - local_buff[size] = '\0'; - - if (inchar != (char) NULL) - local_buff[0] = inchar; /* put in axis */ - - Debug(2, "send_mess(): message = %s\n", local_buff); - - cntrl = (struct IM483controller *) motor_state[card]->DevicePrivate; - - serialIOSend(cntrl->serialInfo, local_buff, strlen(local_buff), SERIAL_TIMEOUT); - if (lastcmnd == OFF) - recv_mess(card, local_buff, 1); - } + cntrl = (struct IM483controller *) motor_state[card]->DevicePrivate; + serialIOSend(cntrl->serialInfo, local_buff, strlen(local_buff), SERIAL_TIMEOUT); - return (0); + return(0); }