newport model 3 driver: reverted back to the old definition of moving axis in the poller in XPSAxis.cpp. I made the new method, of checking the socket return value, an option which is enabled by using a new function called XPSEnableMovingMode. Also added the ability to run a TCL script. This may become a generic function in the base classes later on. Added a Db template to set and execute a TCL script.

This commit is contained in:
mp49
2013-07-12 14:31:22 +00:00
parent 43c538d088
commit 03f345a61c
5 changed files with 172 additions and 17 deletions
+1
View File
@@ -26,6 +26,7 @@ DB += XPSAuxBo.db
DB += XPSAuxLi.db
DB += XPSAuxLo.db
DB += XPS_extra.db
DB += XPSTclScript.template
DB += HXP_extra.db
DB += HXP_coords.db
DB += ACRAux.template
+44
View File
@@ -0,0 +1,44 @@
####################################################
#
# Template for executing TCL script on an XPS.
# Uses parameters in model 3 XPS driver (XPSController).
#
# Matthew Pearson
# July 2013
#
# Macros:
# $(P) - PV name prefix
# $(R) - PV base record name
# $(PORT) - asyn port for the controller
# $(ADDR) - asyn address (normally 0)
# $(TIMEOUT) - asyn timeout
#
####################################################
# ///
# /// Name of the TCL script to execute
# ///
record(waveform, "$(P)$(R)TCLScript")
{
field(DESC, "Name of the TCL script")
field(PINI, "YES")
field(DTYP, "asynOctetWrite")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))XPS_TCL_SCRIPT")
field(FTVL, "CHAR")
field(NELM, "256")
info(autosaveFields, "VAL")
}
# ///
# /// Execute the TCL script (non blocking)
# ///
record(bo, "$(P)$(R)TCLScriptExecute")
{
field(DESC, "Execute TCL Script")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))XPS_TCL_SCRIPT_EXECUTE")
field(ZNAM, "TCL Execute")
field(ONAM, "TCL Execute")
}
+25 -16
View File
@@ -577,28 +577,37 @@ asynStatus XPSAxis::poll(bool *moving)
* homing, jogging, etc. However, this information is about the group, not the axis, so if one
* motor in the group was moving, then they all appeared to be moving. This is not what we want, because
* the EPICS motor record required the first motor to stop before the second motor could be moved.
* Instead we look for a response on the moveSocket_ to see when the motor motion was complete */
* Instead we look for a response on the moveSocket_ to see when the motor motion was complete.
NOTE: by default this mode is disabled. To enable it use the XPSController::enableMovingMode() function.*/
/* If the group is not moving then the axis is not moving */
if ((axisStatus_ < 43) || (axisStatus_ > 48)) moving_ = false;
if ((axisStatus_ < 43) || (axisStatus_ > 48)) {
moving_ = false;
} else {
if (!pC_->enableMovingMode_) {
moving_ = true;
}
}
/* If the axis is moving then read from the moveSocket to see if it is done
* We currently assume the move is complete if we get any response, we don't
* check the actual response. */
if (moving_) {
status = ReadXPSSocket(moveSocket_, readResponse, sizeof(readResponse), 0);
if (status < 0) {
asynPrint(pasynUser_, ASYN_TRACE_ERROR,
"%s:%s: [%s,%d]: error calling ReadXPSSocket status=%d\n",
driverName, functionName, pC_->portName, axisNo_, status);
goto done;
}
if (status > 0) {
asynPrint(pasynUser_, ASYN_TRACE_FLOW,
"%s:%s: [%s,%d]: readXPSSocket returned nRead=%d, [%s]\n",
driverName, functionName, pC_->portName, axisNo_, status, readResponse);
status = 0;
moving_ = false;
if (pC_->enableMovingMode_) {
if (moving_) {
status = ReadXPSSocket(moveSocket_, readResponse, sizeof(readResponse), 0);
if (status < 0) {
asynPrint(pasynUser_, ASYN_TRACE_ERROR,
"%s:%s: [%s,%d]: error calling ReadXPSSocket status=%d\n",
driverName, functionName, pC_->portName, axisNo_, status);
goto done;
}
if (status > 0) {
asynPrint(pasynUser_, ASYN_TRACE_FLOW,
"%s:%s: [%s,%d]: readXPSSocket returned nRead=%d, [%s]\n",
driverName, functionName, pC_->portName, axisNo_, status, readResponse);
status = 0;
moving_ = false;
}
}
}
+90
View File
@@ -169,6 +169,8 @@ XPSController::XPSController(const char *portName, const char *IPAddress, int IP
createParam(XPSProfileGroupNameString, asynParamOctet, &XPSProfileGroupName_);
createParam(XPSTrajectoryFileString, asynParamOctet, &XPSTrajectoryFile_);
createParam(XPSStatusString, asynParamInt32, &XPSStatus_);
createParam(XPSTclScriptString, asynParamOctet, &XPSTclScript_);
createParam(XPSTclScriptExecuteString, asynParamInt32, &XPSTclScriptExecute_);
// This socket is used for polling by the controller and all axes
pollSocket_ = TCP_ConnectToServer((char *)IPAddress, IPPort, XPS_POLL_TIMEOUT);
@@ -209,6 +211,10 @@ XPSController::XPSController(const char *portName, const char *IPAddress, int IP
/* Flag used to turn off setting MSTA problem bit when the axis is disabled.*/
noDisableError_ = 0;
/* Flag to disable a mode to change the moving state determination for an axis.*/
/* See function XPSController::enableMovingMode().*/
enableMovingMode_ = false;
}
void XPSController::report(FILE *fp, int level)
@@ -235,6 +241,51 @@ void XPSController::report(FILE *fp, int level)
asynMotorController::report(fp, level);
}
asynStatus XPSController::writeInt32(asynUser *pasynUser, epicsInt32 value)
{
int function = pasynUser->reason;
int status = asynSuccess;
XPSAxis *pAxis;
static const char *functionName = "writeInt32";
pAxis = this->getAxis(pasynUser);
if (!pAxis) return asynError;
/* Set the parameter and readback in the parameter library. This may be overwritten when we read back the
* status at the end, but that's OK */
status = pAxis->setIntegerParam(function, value);
if (function == XPSTclScriptExecute_) {
/* Execute the TCL script */
char fileName[MAX_FILENAME_LEN];
getStringParam(XPSTclScript_, (int)sizeof(fileName), fileName);
if (fileName != NULL) {
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
"Executing TCL script %s on XPS: %s\n",
fileName, this->portName);
status = TCLScriptExecute(pAxis->moveSocket_,
fileName,"0","0");
if (status != 0) {
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
"TCLScriptExecute returned error %d, on XPS: %s\n",
status, this->portName);
status = asynError;
}
} else {
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
"TCL script name has not been set on XPS: %s\n",
this->portName);
status = asynError;
}
} else {
/* Call base class method */
status = asynMotorController::writeInt32(pasynUser, value);
}
return (asynStatus)status;
}
/**
* Perform a deferred move (a coordinated group move) on all the axes in a group.
* @param groupName Pointer to string naming the group on which to perform the group move.
@@ -1158,6 +1209,18 @@ asynStatus XPSController::noDisableError()
return asynSuccess;
}
/* Function to enable a mode where the XPSAxis poller will check the moveSocket response
to determine motion done. It does not rely on the axis state in this case. This prevents
axes in multipleAxis groups being in 'moving state' when another axis in the same
group is moving. This allows the motor record to move the axis when another axis in the
same group is moving. However, this has the consequence that a moving state is not
detected if the move is externally generated. So by default this mode is turned off. It
can be enabled by calling this function. */
asynStatus XPSController::enableMovingMode()
{
enableMovingMode_ = true;
return asynSuccess;
}
@@ -1257,6 +1320,22 @@ asynStatus XPSNoDisableError(const char *XPSName)
return pC->noDisableError();
}
asynStatus XPSEnableMovingMode(const char *XPSName)
{
XPSController *pC;
static const char *functionName = "XPSEnableMovingMode";
pC = (XPSController*) findAsynPortDriver(XPSName);
if (!pC) {
printf("%s:%s: Error port %s not found\n", driverName, functionName, XPSName);
return asynError;
}
return pC->enableMovingMode();
}
/* Code for iocsh registration */
@@ -1342,6 +1421,16 @@ static void noDisableErrorCallFunc(const iocshArgBuf *args)
XPSNoDisableError(args[0].sval);
}
/* XPSEnableMovingMode */
static const iocshArg XPSEnableMovingModeArg0 = {"Controller port name", iocshArgString};
static const iocshArg * const XPSEnableMovingModeArgs[] = {&XPSEnableMovingModeArg0};
static const iocshFuncDef enableMovingMode = {"XPSEnableMovingMode", 1, XPSEnableMovingModeArgs};
static void enableMovingModeCallFunc(const iocshArgBuf *args)
{
XPSEnableMovingMode(args[0].sval);
}
static void XPSRegister3(void)
{
@@ -1350,6 +1439,7 @@ static void XPSRegister3(void)
iocshRegister(&configXPSProfile, configXPSProfileCallFunc);
iocshRegister(&disableAutoEnable, disableAutoEnableCallFunc);
iocshRegister(&noDisableError, noDisableErrorCallFunc);
iocshRegister(&enableMovingMode, enableMovingModeCallFunc);
}
epicsExportRegistrar(XPSRegister3);
+12 -1
View File
@@ -25,6 +25,8 @@ USAGE... Newport XPS EPICS asyn motor device driver
#define XPSProfileGroupNameString "XPS_PROFILE_GROUP_NAME"
#define XPSTrajectoryFileString "XPS_TRAJECTORY_FILE"
#define XPSStatusString "XPS_STATUS"
#define XPSTclScriptString "XPS_TCL_SCRIPT"
#define XPSTclScriptExecuteString "XPS_TCL_SCRIPT_EXECUTE"
class XPSController : public asynMotorController {
@@ -34,6 +36,7 @@ class XPSController : public asynMotorController {
int enableSetPosition, double setPositionSettlingTime);
/* These are the methods that we override from asynMotorDriver */
asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
void report(FILE *fp, int level);
XPSAxis* getAxis(asynUser *pasynUser);
XPSAxis* getAxis(int axisNo);
@@ -60,6 +63,11 @@ class XPSController : public asynMotorController {
/* Function to disable the MSTA problem bit in the event of an XPS Disable state 20 */
asynStatus noDisableError();
/* Function to enable a mode where the XPSAxis poller will check the moveSocket response
to determine motion done. */
asynStatus enableMovingMode();
protected:
XPSAxis **pAxes_; /**< Array of pointers to axis objects */
@@ -73,7 +81,9 @@ class XPSController : public asynMotorController {
int XPSProfileGroupName_;
int XPSTrajectoryFile_;
int XPSStatus_;
#define LAST_XPS_PARAM XPSStatus_
int XPSTclScript_;
int XPSTclScriptExecute_;
#define LAST_XPS_PARAM XPSTclScriptExecute_
private:
bool enableSetPosition_; /**< Enable/disable setting the position from EPICS */
@@ -89,6 +99,7 @@ class XPSController : public asynMotorController {
epicsEventId profileExecuteEvent_;
int autoEnable_;
int noDisableError_;
bool enableMovingMode_;
friend class XPSAxis;
};