From 5bc87d63f286743efce37ad8bb766d1d2182c46e Mon Sep 17 00:00:00 2001 From: Ron Sluiter Date: Tue, 27 May 2014 16:39:49 +0000 Subject: [PATCH] Bug fixes copied from trunk. See motor_release.html for details. --- documentation/motor_release.html | 50 ++++++++++++++++ motorApp/MclennanSrc/devPM304.cc | 5 +- motorApp/MclennanSrc/drvPM304.cc | 7 ++- motorApp/MicosSrc/devMicos.cc | 3 +- motorApp/MotorSrc/motorRecord.cc | 14 ++++- motorApp/NewportSrc/README | 82 +++++++++++++++++++++++--- motorApp/NewportSrc/devESP300.cc | 10 ++-- motorApp/NewportSrc/drvESP300.cc | 42 +++++++++----- motorApp/OmsSrc/devOmsCom.cc | 13 +++-- motorApp/OmsSrc/drvMAXv.cc | 98 +++++++++++++++++++------------- motorApp/OmsSrc/drvMAXv.h | 1 + motorApp/OmsSrc/drvOms.cc | 6 +- 12 files changed, 250 insertions(+), 81 deletions(-) diff --git a/documentation/motor_release.html b/documentation/motor_release.html index 580ad549..3c9ebc93 100644 --- a/documentation/motor_release.html +++ b/documentation/motor_release.html @@ -12,6 +12,56 @@ + +
+

Motor Record Version 6-8-1 Release Notice

+
+
+

Modifications to Existing Features

+
+
+

motor record

+

+ Previous to this release, if an EPICS motor driver signaled a controller error + by setting the RA_PROBLEM bit of the MSTA filed true, then the motor record + assumed that the controller had stopped motor motion. In some cases this was not + true. For example, if a Newport ESP300 controller's maximum velocity parameter + is exceeded, the controller signals an error, but then continues jogging the + motor at the maximum velocity parameter value. +

+

+ With this release, the motor record stops motion whenever RA_PROBLEM is set true. +

+ +

Newport ESP100/300/301

+

+ The changes made to the Newport ESP100/300/301 driver in the previous release (R6-8) + were rolled back. Since the motor record's data structure is not always + available to driver level code, using MRES to scale the EGUtoRAWbacktoEGU + conversion proved to be unworkable. +

+ +

OMS MAXv limit mode

+

+ Since the default mode of the limit switches is "Off" on some OMS MAXv firmware + versions after 1.30, during iocInit, if the limit mode is "Off" the driver will + set the limit mode to "Hard". +

+ +

Micos MoCo

+

+ Bug fix for protection against NULL *parms pointer from motor record. +

+ +

Mclennan PM304

+

+ Bug fixes for both protection against NULL *parms pointer from motor record and + incorrect epicsStrtok_r() argument. +

+
+

+

+

Motor Record Version 6-8 Release Notice

diff --git a/motorApp/MclennanSrc/devPM304.cc b/motorApp/MclennanSrc/devPM304.cc index 63797b23..2cfb2e5d 100644 --- a/motorApp/MclennanSrc/devPM304.cc +++ b/motorApp/MclennanSrc/devPM304.cc @@ -175,8 +175,9 @@ STATIC RTN_STATUS PM304_build_trans(motor_cmnd command, double *parms, struct mo rtnval = OK; buff[0] = '\0'; - dval = parms[0]; - ival = NINT(parms[0]); + /* Protect against NULL pointer with WRTITE_MSG(GO/STOP_AXIS/GET_INFO, NULL). */ + dval = (parms == NULL) ? 0.0 : *parms; + ival = NINT(dval); motor_call = &(trans->motor_call); card = motor_call->card; diff --git a/motorApp/MclennanSrc/drvPM304.cc b/motorApp/MclennanSrc/drvPM304.cc index e7030827..273992cd 100644 --- a/motorApp/MclennanSrc/drvPM304.cc +++ b/motorApp/MclennanSrc/drvPM304.cc @@ -356,6 +356,7 @@ STATIC RTN_STATUS send_mess(int card, const char *com, char *name) { char *p, *tok_save; char response[BUFF_SIZE]; + char temp[BUFF_SIZE]; struct PM304controller *cntrl; size_t nwrite, nread; int eomReason; @@ -372,7 +373,8 @@ STATIC RTN_STATUS send_mess(int card, const char *com, char *name) /* Device support can send us multiple commands separated with ';' * characters. The PM304 cannot handle more than 1 command on a line * so send them separately */ - for (p = epicsStrtok_r((char *) com, ";", &tok_save); + strcpy(temp, com); + for (p = epicsStrtok_r(temp, ";", &tok_save); ((p != NULL) && (strlen(p) != 0)); p = epicsStrtok_r(NULL, ";", &tok_save)) { Debug(2, "send_mess: sending message to card %d, message=%s\n", card, p); @@ -487,7 +489,8 @@ STATIC int send_recv_mess(int card, const char *out, char *response) /* Device support can send us multiple commands separated with ';' * characters. The PM304 cannot handle more than 1 command on a line * so send them separately */ - for (p = epicsStrtok_r((char *) out, ";", &tok_save); + strcpy(temp, out); + for (p = epicsStrtok_r(temp, ";", &tok_save); ((p != NULL) && (strlen(p) != 0)); p = epicsStrtok_r(NULL, ";", &tok_save)) { Debug(2, "send_recv_mess: sending message to card %d, message=%s\n", card, p); diff --git a/motorApp/MicosSrc/devMicos.cc b/motorApp/MicosSrc/devMicos.cc index 81e898f3..d57f70ef 100644 --- a/motorApp/MicosSrc/devMicos.cc +++ b/motorApp/MicosSrc/devMicos.cc @@ -157,7 +157,8 @@ static RTN_STATUS Micos_build_trans(motor_cmnd command, double *parms, struct mo rtnval = OK; buff[0] = '\0'; - dval = parms[0]; + /* Protect against NULL pointer with WRTITE_MSG(GO/STOP_AXIS/GET_INFO, NULL). */ + dval = (parms == NULL) ? 0.0 : *parms; ival = NINT(parms[0]); rtnval = (RTN_STATUS) motor_start_trans_com(mr, Micos_cards); diff --git a/motorApp/MotorSrc/motorRecord.cc b/motorApp/MotorSrc/motorRecord.cc index e48cbfbd..0f12a094 100644 --- a/motorApp/MotorSrc/motorRecord.cc +++ b/motorApp/MotorSrc/motorRecord.cc @@ -173,9 +173,12 @@ HeadURL: $URL$ * No need in process() to test MIP_MOVE type moves for soft-travel limits. * - Need "preferred_dir" for LVIO test. Moved LVIO test in do_work() to * after "preferred_dir" is set. + * .69 05-19-14 rls - Set "stop" field true if driver returns RA_PROBLEM true. (Motor record + * stops motion when controller signals error but does not stop motion; e.g., + * maximum velocity exceeded.) */ -#define VERSION 6.8 +#define VERSION 6.81 #include #include @@ -3584,8 +3587,15 @@ static void if (ls_active == true || msta.Bits.RA_DONE || msta.Bits.RA_PROBLEM) { pmr->movn = 0; - if (ls_active == true) + if (ls_active == true || msta.Bits.RA_PROBLEM) + { clear_buttons(pmr); + if (msta.Bits.RA_PROBLEM) + { + pmr->stop = 1; + MARK(M_STOP); + } + } } else pmr->movn = 1; diff --git a/motorApp/NewportSrc/README b/motorApp/NewportSrc/README index f5abdffd..dc98c04f 100644 --- a/motorApp/NewportSrc/README +++ b/motorApp/NewportSrc/README @@ -18,14 +18,82 @@ Octal I/O manual is jumpered as follows; 1-5, 2-6, 9-13, 10-14. The correct jumpering for the ESP300 is; 1-5, 2-6, 9-13, 10-11, 15-16. -Setting the motor resolution (MRES) field. ------------------------------------------- +Setting the motor resolution (MRES) and Engineering Units fields to the +SAME values as the controller's. +------------------------------------------------------------------------- -Set the MRES like any other motor; i.e., to the precision of the stage. -(Prior to motor module R6.8, the driver used the controllers resolution -to scale the EGUtoRAWbacktoEGU conversion done between motor record and -device driver support. With R6.8 the driver uses the motor record's MRES -to scale the conversion). +For DC motors, set MRES to the ESP300's response to the SU? command. + +If there is no other mechanism (e.g., generic serial record, dumb terminal, +etc.) to communicate to the ESP300, the response to the SU? command can be +determined by following this procedure; + +1 - uncomment the "USR_CFLAGS += -DDEBUG" line in the NewportSrc/Makefile.Vx + file (This selects the diagnostic messages to be compiled). +2 - "cd /motorApp/NewportSrc; gnumake clean; gnumake"; this re-compiles + the device drivers with the diagnostic messages selected. +3 - Rebuild your IOC; "cd ; gnumake". +4 - Add "drvESP300debug = 4" to the IOC's st.cmd file before "iocInit". +5 - Connect to the VxWorks shell and reboot the IOC. + +The VxWorks shell output should contain lines like the following; + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Starting iocInit +send_mess(): message = VE? +recv_mess(): message = "ESP300 Version 3.08 09/09/02" +send_mess(): message = ZU +recv_mess(): message = "0H" +send_mess(): message = 01ST +send_mess(): message = 02ST +send_mess(): message = 03ST +send_mess(): message = 01SN? +recv_mess(): message = "2" +send_mess(): message = 01SU? +recv_mess(): message = "0.00003539317" +send_mess(): message = 01MD +recv_mess(): message = "1" +send_mess(): message = 01TP +recv_mess(): message = "0.00000" +send_mess(): message = 01PH +recv_mess(): message = "18000606H, 6H" +send_mess(): message = 01MO? +recv_mess(): message = "0" +send_mess(): message = 01TE? +recv_mess(): message = "0" +send_mess(): message = 02SN? +recv_mess(): message = "2" +send_mess(): message = 02SU? +recv_mess(): message = "0.00009765625" ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Note the response to the SU? and SN? commands and set MRES to that value. + +All three supported controllers (ESP100/300/301) have the same response +to the SN? command; 0 to 10 where +0 = encoder count 6 = micro-inches +1 = motor step 7 = degree +2 = millimeter 8 = gradian +3 = micrometer 9 = radian +4 = inches 10 = milliradian +5 = milli-inches 11 = microradian + +5 - Set the motor record's EGU field to "mm" (based on SN-2) and the MRES field + to 3.539317E-5 (based on SU = 0.00003539317). +6 - Turn off diagnostic messages. Either set drvESP300debug = 0 in the st.cmd + file (there is a very small amount of CPU overhead associated with leaving + the diagnostic messages loaded), or go to step #1, and reverse the steps; + comment out the "USR_CFLAGS += -DDEBUG" line in the NewportSrc/Makefile.Vx, + etc., etc., + +Setting the motor record's Engineering Units field (EGU) to a value DIFFERENT +from the controller's EGU. +------------------------------------------------------------------------------- +In the above example the controller returned SU = "0.00003539317" and SN = "2" +for axis #1. If the user prefers the motor record EGU to be in inches rather +than millimeters, then set EGU = "inch" and, +MRES = (3.539317E-5 mm / 1 encoder tick) X (1 inch / 25.4 mm) + = 1.39343189E-6 inch / 1 encoder tick Newport ESP100 ============== diff --git a/motorApp/NewportSrc/devESP300.cc b/motorApp/NewportSrc/devESP300.cc index 18eb9ef2..b50fc5ab 100644 --- a/motorApp/NewportSrc/devESP300.cc +++ b/motorApp/NewportSrc/devESP300.cc @@ -2,9 +2,10 @@ FILENAME... devESP300.cc USAGE... Motor record device level support for Newport ESP300. -Version: $Revision: 1.4 $ -Modified By: $Author: sluiter $ -Last Modified: $Date: 2008-03-14 20:17:14 $ +Version: $Revision$ +Modified By: $Author$ +Last Modified: $Date$ +HeadURL: $URL$ */ /* @@ -37,7 +38,6 @@ Last Modified: $Date: 2008-03-14 20:17:14 $ * ----------------- * .01 05-23-03 rls Converted to R3.14.x. * .02 10-28-03 rls User must set MRES to drive resolution. - * .03 13-22-02 rls Use MRES rather than drive resolution. */ #include @@ -188,7 +188,7 @@ static RTN_STATUS ESP300_build_trans(motor_cmnd command, double *parms, struct m return(rtnval = ERROR); cntrl = (struct MMcontroller *) brdptr->DevicePrivate; - cntrl_units = dval * mr->mres; + cntrl_units = dval * cntrl->drive_resolution[axis - 1]; if (ESP300_table[command] > motor_call->type) motor_call->type = ESP300_table[command]; diff --git a/motorApp/NewportSrc/drvESP300.cc b/motorApp/NewportSrc/drvESP300.cc index a66a0c7b..19ba35c8 100644 --- a/motorApp/NewportSrc/drvESP300.cc +++ b/motorApp/NewportSrc/drvESP300.cc @@ -53,14 +53,13 @@ HeadURL: $URL$ * extern "C" linkage. * .09 08/07/06 rls - GPIB under ASYN only allows 1 input EOS character. * No output EOS. Adjustments accordingly. - * .10 02/22/13 rls - Scrap driver resolution, use MRES. + * .10 05/19/14 rls - Print controller's error code and set RA_PROBLEM. */ #include #include #include -#include "motorRecord.h" #include "motor.h" #include "NewportRegister.h" #include "drvMMCom.h" @@ -216,23 +215,15 @@ static int set_status(int card, int signal) /* Message parsing variables */ char *cptr, *tok_save; char inbuff[BUFF_SIZE], outbuff[BUFF_SIZE]; - int rtn_state, charcnt; + int rtn_state, charcnt, errcode; long mstatus; - double motorData, MRES; + double motorData; bool power, plusdir, ls_active = false; msta_field status; - struct motorRecord *mr; cntrl = (struct MMcontroller *) motor_state[card]->DevicePrivate; motor_info = &(motor_state[card]->motor_info[signal]); nodeptr = motor_info->motor_motion; - if (nodeptr != NULL) - { - mr = (struct motorRecord *) nodeptr->mrecord; - MRES = mr->mres; - } - else - MRES = 1.0; status.All = motor_info->status.All; @@ -270,7 +261,7 @@ static int set_status(int card, int signal) send_mess(card, outbuff, (char) NULL); charcnt = recv_mess(card, inbuff, 1); - motorData = atof(inbuff) / MRES; + motorData = atof(inbuff) / cntrl->drive_resolution[signal]; if (motorData == motor_info->position) { @@ -340,7 +331,19 @@ static int set_status(int card, int signal) status.Bits.EA_SLIP = 0; status.Bits.EA_SLIP_STALL = 0; status.Bits.EA_HOME = 0; - status.Bits.RA_PROBLEM = 0; + + /* Get error code. */ + sprintf(outbuff, "%.2dTE?", signal + 1); + send_mess(card, outbuff, (char) NULL); + charcnt = recv_mess(card, inbuff, 1); + errcode = atoi(inbuff); + if (errcode != 0) + { + status.Bits.RA_PROBLEM = 1; + printf("ESP300 controller error = %d.\n", errcode); + } + else + status.Bits.RA_PROBLEM = 0; /* Parse motor velocity? */ /* NEEDS WORK */ @@ -675,6 +678,17 @@ errexit: { struct mess_info *motor_info = &brdptr->motor_info[motor_index]; + /* Get controller's EGU for the user (see README). */ + sprintf(buff, "%.2dSN?", motor_index + 1); + send_mess(card_index, buff, 0); + recv_mess(card_index, buff, 1); + + /* Set axis resolution. */ + sprintf(buff, "%.2dSU?", motor_index + 1); + send_mess(card_index, buff, 0); + recv_mess(card_index, buff, 1); + cntrl->drive_resolution[motor_index] = atof(&buff[0]); + motor_info->status.All = 0; motor_info->no_motion_count = 0; motor_info->encoder_position = 0; diff --git a/motorApp/OmsSrc/devOmsCom.cc b/motorApp/OmsSrc/devOmsCom.cc index 36b49c86..60d41107 100644 --- a/motorApp/OmsSrc/devOmsCom.cc +++ b/motorApp/OmsSrc/devOmsCom.cc @@ -208,7 +208,7 @@ RTN_STATUS oms_build_trans(motor_cmnd command, double *parms, struct motorRecord struct motor_trans *trans = (struct motor_trans *) mr->dpvt; struct mess_node *motor_call; struct controller *brdptr; - struct MAXvController *MAXvCntrl; + struct MAXvController *MAXvCntrl = NULL; char buffer[40]; msg_types cmnd_type; RTN_STATUS rtnind; @@ -230,7 +230,8 @@ RTN_STATUS oms_build_trans(motor_cmnd command, double *parms, struct motorRecord if (trans->state != BUILD_STATE) return(rtnind = ERROR); - brdptr = (*trans->tabptr->card_array)[card]; + if ((brdptr = (*trans->tabptr->card_array)[card]) == NULL) /* Test for disabled board. */ + return(rtnind = ERROR); if (strncmp(brdptr->ident, "MAXv", 4) == 0) { @@ -284,8 +285,8 @@ RTN_STATUS oms_build_trans(motor_cmnd command, double *parms, struct motorRecord else strcpy(buffer, mr->init); - strcat(motor_call->message, " "); strcat(motor_call->message, buffer); + strcat(motor_call->message, ";"); } else { @@ -451,9 +452,9 @@ errorexit: errMessage(-1, "Invalid device directive"); case SET_IGAIN: case SET_DGAIN: if (MAXv == true) - sprintf(buffer, "%.1f", (parms[itera] * 32767.0)); + sprintf(buffer, "%.1f;", (parms[itera] * 32767.0)); else - sprintf(buffer, "%.1f", (parms[itera] * 1999.9)); + sprintf(buffer, "%.1f;", (parms[itera] * 1999.9)); break; case SET_VELOCITY: /* OMS errors if VB = VL. */ @@ -518,7 +519,7 @@ errorexit: errMessage(-1, "Invalid device directive"); break; case LOAD_POS: - if ((MAXv == true) && (MAXvCntrl->typeID[signal] != PSO)) + if ((MAXv == true) && (MAXvCntrl != NULL) && (MAXvCntrl->typeID[signal] != PSO) && (MAXvCntrl->fwver > 1.29)) { long int ref = NINT(parms[0]); long int fdbk = ref; diff --git a/motorApp/OmsSrc/drvMAXv.cc b/motorApp/OmsSrc/drvMAXv.cc index 5bc815d9..d8644ba5 100644 --- a/motorApp/OmsSrc/drvMAXv.cc +++ b/motorApp/OmsSrc/drvMAXv.cc @@ -36,13 +36,17 @@ HeadURL: $URL$ * * NOTES * ----- - * Verified with firmware: - * - MAXv ver:1.25 - * - MAXv ver:1.29 (has ECO #1432; fixes initialization problem). - * - MAXv ver:1.31 (fixes DPRAM encoder position data problem when using - * mixed motor types.) - * - MAXv ver:1.33, FPGA:B2:A6 BOOT:1.2 (Watchdog Timeout Counter added) - * - MAXv ver:1.34, FPGA:03:A6 BOOT:1.3 + * Verified with MAXv firmware: + * - ver:1.25 + * - ver:1.29 (has ECO #1432; fixes initialization problem). + * - ver:1.31 (fixes DPRAM encoder position data problem when using + * mixed motor types.) + * - ver:1.33, FPGA:B2:A6 BOOT:1.2 (Watchdog Timeout Counter added) + * - ver:1.34, FPGA:03:A6 BOOT:1.3 + * - ver:1.41 & 1.42, suffers from having limit switches disabled at + * power-up. + * - ver:1.44, No known problems. + * - ver:1.45, limit switches are disabled by default. * * Modification Log: * ----------------- @@ -94,7 +98,8 @@ HeadURL: $URL$ * motor record to store motor type. Motor type used in * device support (devOmsCom.cc) to allow MRES and ERES with * different polarity (signs). - * + * 24 02-24-14 rls - After the initialization string is read, if limit mode is + * "Off", set it to "Hard". */ #include @@ -171,6 +176,8 @@ static char *MAXv_axis[] = {"X", "Y", "Z", "T", "U", "V", "R", "S"}; static double quantum; static char **initstring = 0; static epicsUInt32 MAXv_brd_size; /* card address boundary */ +static char cmndbuf[MAX_MSG_SIZE]; /* Command buffer used by send_mess() and + * motorIsr if there is a "command error"*/ /* First 8-bits [0..7] used to indicate absolute or */ /* incremental position registers to be read */ @@ -265,11 +272,6 @@ extern "C" {epicsExportAddress(drvet, drvMAXv);} static struct thread_args targs = {SCAN_RATE, &MAXv_access, 0.000}; -static struct MAXvbrdinfo /* MAXv board info. */ -{ - float fwver[MAXv_NUM_CARDS]; /* firmware version */ -} MAXvdata; - static char wdctrmsg[] = "\n***MAXv card #%d Disabled*** Watchdog Timeout CTR %s\n\n"; static char norunmsg[] = "\n*** MAXv card #%d is NOT running *** status = 0x%x\n"; @@ -368,6 +370,9 @@ static int set_status(int card, int signal) char *p, *tok_save; struct axis_status *ax_stat; struct encoder_status *en_stat; + struct controller *brdptr; + struct MAXvController *MAXvCntrl; + char q_buf[MAX_IDENT_LEN], outbuf[50]; int index; bool ls_active = false; @@ -383,7 +388,11 @@ static int set_status(int card, int signal) pmotor = (struct MAXv_motor *) motor_state[card]->localaddr; status.All = motor_info->status.All; - if (MAXvdata.fwver[card] >= 1.33) + if ((brdptr = motor_state[card]) == NULL) /* Test for board disabled. */ + return(rtn_state = 1); /* End move. */ + + MAXvCntrl = (struct MAXvController *) brdptr->DevicePrivate; + if (MAXvCntrl->fwver >= 1.33) { send_recv_mess(card, "#WS", (char) NULL, q_buf, 1); if (strcmp(q_buf, "=0") != 0) @@ -609,7 +618,7 @@ static RTN_STATUS send_mess(int card, char const *com, char *name) { volatile struct MAXv_motor *pmotor; epicsInt16 putIndex; - char outbuf[MAX_MSG_SIZE], *p; + char *pcmndbuf; RTN_STATUS return_code; int count; @@ -642,31 +651,31 @@ static RTN_STATUS send_mess(int card, char const *com, char *name) if (pmotor->inGetIndex != pmotor->inPutIndex) { Debug(1, "send_mess - clearing data in buffer\n"); - recv_mess(card, outbuf, FLUSH); + recv_mess(card, cmndbuf, FLUSH); } if (name == NULL) - strcpy(outbuf, com); + strcpy(cmndbuf, com); else { - strcpy(outbuf, "A"); - strcat(outbuf, name); - strcat(outbuf, " "); - strcat(outbuf, com); + strcpy(cmndbuf, "A"); + strcat(cmndbuf, name); + strcat(cmndbuf, " "); + strcat(cmndbuf, com); } Debug(9, "send_mess: ready to send message.\n"); putIndex = pmotor->outPutIndex; - for (p = outbuf; *p != '\0'; p++) + for (pcmndbuf = cmndbuf; *pcmndbuf != '\0'; pcmndbuf++) { - pmotor->outBuffer[putIndex++] = *p; + pmotor->outBuffer[putIndex++] = *pcmndbuf; if (putIndex >= BUFFER_SIZE) putIndex = 0; } Debug(4, "send_mess: sent card %d message:", card); - Debug(4, "%s\n", outbuf); + Debug(4, "%s\n", cmndbuf); pmotor->outPutIndex = putIndex; /* Message Sent */ @@ -1008,7 +1017,7 @@ MAXvSetup(int num_cards, /* maximum number of cards in rack */ RTN_VALUES MAXvConfig(int card, /* number of card being configured */ const char *initstr, /* configuration string */ - int config) /* initialization configuration */ + int AbsConfig) /* absolute encoder configuration */ { if (card < 0 || card >= MAXv_num_cards) { @@ -1026,9 +1035,9 @@ RTN_VALUES MAXvConfig(int card, /* number of card being configur } strcpy(initstring[card], initstr); - /* get the configuation flags */ - configurationFlags[card] = config; - + /* Save absolute encoder and grey code configuation flags */ + configurationFlags[card] = AbsConfig; + return(OK); } @@ -1042,13 +1051,13 @@ static void motorIsr(int card) volatile struct controller *pmotorState; volatile struct MAXv_motor *pmotor; STATUS1 status1_flag; - static char errmsg1[] = "\ndrvMAXv.cc:motorIsr: Invalid entry - card xx\n"; - static char errmsg2[] = "\ndrvMAXv.cc:motorIsr: command error - card xx\n"; + static char errmsg1[] = "drvMAXv.cc:motorIsr: ***Invalid entry*** - card xx\n"; + static char errmsg2[] = "drvMAXv.cc:motorIsr: ***Command Error*** - card xx\n"; if (card >= total_cards || (pmotorState = motor_state[card]) == NULL) { - errmsg1[46-2] = '0' + card%10; - errmsg1[46-3] = '0' + (card/10)%10; + errmsg1[51-2] = '0' + card%10; + errmsg1[51-3] = '0' + (card/10)%10; epicsInterruptContextMessage(errmsg1); return; } @@ -1062,9 +1071,11 @@ static void motorIsr(int card) if (status1_flag.Bits.cmndError) { - errmsg2[46-2] = '0' + card%10; - errmsg2[46-3] = '0' + (card/10)%10; + errmsg2[51-2] = '0' + card%10; + errmsg2[51-3] = '0' + (card/10)%10; epicsInterruptContextMessage(errmsg2); + strcat(cmndbuf,"\n\n"); + epicsInterruptContextMessage(cmndbuf); } if (status1_flag.Bits.text_response != 0) /* Don't clear this. */ @@ -1240,13 +1251,13 @@ static int motor_init() send_recv_mess(card_index, GET_IDENT, (char) NULL, (char *) pmotorState->ident, 1); Debug(3, "Identification = %s\n", pmotorState->ident); - /* Save firmware version to static float array. */ + /* Save firmware version. */ pos_ptr = strchr((char *)pmotorState->ident, ':'); - sscanf(++pos_ptr, "%f", &MAXvdata.fwver[card_index]); + sscanf(++pos_ptr, "%f", &pvtdata->fwver); wdtrip = false; - if (MAXvdata.fwver[card_index] >= 1.33) + if (pvtdata->fwver >= 1.33) { send_recv_mess(card_index, "#WS", (char) NULL, axis_pos, 1); if (strcmp(axis_pos, "=0") != 0) @@ -1323,6 +1334,13 @@ static int motor_init() pvtdata->typeID[motor_index] = PSE; else pvtdata->typeID[motor_index] = PSO; + + if (pvtdata->fwver >= 1.30) + { + send_recv_mess(card_index, "LM?", MAXv_axis[motor_index], axis_pos, 1); + if (strcmp(axis_pos, "=f") == 0) /* If limit mode is set to "Off". */ + send_mess(card_index, "LMH", MAXv_axis[motor_index]); /* Set limit mode to "Hard". */ + } } /* Enable interrupt-when-done if selected */ @@ -1410,11 +1428,11 @@ extern "C" static const iocshArg setupArg2 = {"Base Address on 4K (0x1000) boundary", iocshArgInt}; static const iocshArg setupArg3 = {"noninterrupting(0), valid vectors(64-255)", iocshArgInt}; static const iocshArg setupArg4 = {"interrupt level (1-6)", iocshArgInt}; - static const iocshArg setupArg5 = {"polling rate - 1/60 sec units", iocshArgInt}; + static const iocshArg setupArg5 = {"polling rate (Hz)", iocshArgInt}; // Oms Config arguments - static const iocshArg configArg0 = {"Card being configured", iocshArgInt}; + static const iocshArg configArg0 = {"Card # being configured", iocshArgInt}; static const iocshArg configArg1 = {"configuration string", iocshArgString}; - static const iocshArg configArg2 = {"configuration flags", }; + static const iocshArg configArg2 = {"absolute encoder flags (0/1 - incremental/absolute, 0x07 -> ZYX)", iocshArgInt}; static const iocshArg * const OmsSetupArgs[6] = {&setupArg0, &setupArg1, &setupArg2, &setupArg3, &setupArg4, &setupArg5}; diff --git a/motorApp/OmsSrc/drvMAXv.h b/motorApp/OmsSrc/drvMAXv.h index 730505d6..18fee94b 100644 --- a/motorApp/OmsSrc/drvMAXv.h +++ b/motorApp/OmsSrc/drvMAXv.h @@ -65,6 +65,7 @@ enum MotorTypes {PSO, // Stepper; w/o encoder struct MAXvController { MotorTypes typeID[8]; + float fwver; /* firmware version */ epicsMutexId message_mutex; }; diff --git a/motorApp/OmsSrc/drvOms.cc b/motorApp/OmsSrc/drvOms.cc index b56fd1f1..6ee46d26 100644 --- a/motorApp/OmsSrc/drvOms.cc +++ b/motorApp/OmsSrc/drvOms.cc @@ -82,6 +82,8 @@ HeadURL: $URL$ * .17 07-26-12 rls - Added reboot flag to IRQ control register. Driver * sets IRQ_RESET_ID bit on; set_status() and send_mess() * read IRQ register and disable board if flag is off. + * .18 11-15-03 rls - Added bus flushing read on exit from ISR to prevent + * "out of order transactions". */ /*========================stepper motor driver ======================== @@ -900,8 +902,8 @@ static void motorIsr(int card) } irqdata->recv_sem->signal(); } - /* Update-interrupt state */ - pmotor->control = control; + pmotor->control = control; /* Update-interrupt state. */ + control = pmotor->control; /* Read it back to flush last write cycle. */ } static int motorIsrEnable(int card)