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)