Add a set PV for the SeleneMotor
- make the number of extra parameters in SINQController configurable - add database entry for the motor set field - add the new function "setMotorPosition_" to the Selene controller - execute Qx59=<pos> to set the new position
This commit is contained in:
@ -25,17 +25,20 @@ TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
||||
#SNCSEQ=$(EPICS_BASE)/../modules/soft/seq
|
||||
|
||||
# EPICS_BASE usually appears last so other apps can override stuff:
|
||||
EPICS_BASE=/opt/epics/bases/base-3.14.12.5
|
||||
|
||||
#EPICS_BASE=
|
||||
#MODULES=/home/epics/modules
|
||||
|
||||
# Set RULES here if you want to take build rules from somewhere
|
||||
# other than EPICS_BASE:
|
||||
#RULES=/path/to/epics/support/module/rules/x-y
|
||||
MOTOR=/opt/epics/modules/motor/6.10.0/3.14.12.5
|
||||
ASYN=/opt/epics/modules/asyn/4.27.0/3.14.12.5
|
||||
SYNAPPSSTD=/opt/epics/modules/synAppsStd/3.4.1/3.14.12.5/
|
||||
#ANC=/usr/local/epics/anc350v17
|
||||
STREAMS=/opt/epics/modules/streamdevice/2.6.0/3.14.12.5
|
||||
#LAKESHORE336=/usr/local/epics/support/lakeshore336
|
||||
BUSY=/opt/epics/modules/busy/1.6.0/3.14.12.5
|
||||
#OXINSTCRYOJET=/usr/local/epics/support/OxInstCryojet-2-18-3
|
||||
PCRE=/opt/epics/modules/pcre/8.36.0/3.14.12.5
|
||||
##RULES=/path/to/epics/support/module/rules/x-y
|
||||
#MOTOR=/opt/epics/modules/motor/6.10.0/3.14.12.5
|
||||
#ASYN=/opt/epics/modules/asyn/4.27.0/3.14.12.5
|
||||
#SYNAPPSSTD=/opt/epics/modules/synAppsStd/3.4.1/3.14.12.5/
|
||||
##ANC=/usr/local/epics/anc350v17
|
||||
#STREAMS=/opt/epics/modules/streamdevice/2.6.0/3.14.12.5
|
||||
##LAKESHORE336=/usr/local/epics/support/lakeshore336
|
||||
#BUSY=/opt/epics/modules/busy/1.6.0/3.14.12.5
|
||||
##OXINSTCRYOJET=/usr/local/epics/support/OxInstCryojet-2-18-3
|
||||
#PCRE=/opt/epics/modules/pcre/8.36.0/3.14.12.5
|
||||
|
||||
|
6
sinqEPICSApp/Db/motorSet.db
Normal file
6
sinqEPICSApp/Db/motorSet.db
Normal file
@ -0,0 +1,6 @@
|
||||
# workaround over set position
|
||||
record(ao, "$(P)$(M)-SetPosition") {
|
||||
field(DTYP, "asynFloat64")
|
||||
field(OUT, "@asyn($(PORT),$(N),1) SET_MOTOR_POSITION")
|
||||
field(PINI, "YES")
|
||||
}
|
@ -10,8 +10,8 @@
|
||||
#include "SINQController.h"
|
||||
#include "asynMotorController.h"
|
||||
|
||||
SINQController::SINQController(const char *portName, const char *SINQPortName, int numAxes)
|
||||
: asynMotorController(portName, numAxes+1, NUM_MOTOR_DRIVER_PARAMS+2,
|
||||
SINQController::SINQController(const char *portName, const char *SINQPortName, int numAxes, const int& extraParams)
|
||||
: asynMotorController(portName, numAxes+1, NUM_MOTOR_DRIVER_PARAMS+extraParams,
|
||||
0, // No additional interfaces beyond those in base class
|
||||
0, // No additional callback interfaces beyond those in base class
|
||||
ASYN_CANBLOCK | ASYN_MULTIDEVICE,
|
||||
|
@ -17,7 +17,7 @@
|
||||
class epicsShareClass SINQController : public asynMotorController
|
||||
{
|
||||
public:
|
||||
SINQController(const char *portName, const char *SINQPortName, int numAxes);
|
||||
SINQController(const char *portName, const char *SINQPortName, int numAxes, const int& extraParams=2);
|
||||
|
||||
friend class SINQAxis;
|
||||
protected:
|
||||
|
@ -8,9 +8,9 @@
|
||||
* 23 May 2012
|
||||
*
|
||||
* Substantially modified for use at SINQ at PSI.
|
||||
* The thing with the PMACS is that they can be programmed.
|
||||
* The thing with the PMAC's is that they can be programmed.
|
||||
* This affects also the commands they understand.
|
||||
* Our PMACS also do not seem to like to return multiple replies.....
|
||||
* Our PMAC's also do not seem to like to return multiple replies.....
|
||||
*
|
||||
* I use a starting flag to catch a peculiar feature of our PMAC implementation:
|
||||
* when the motor is hung, it wont start. I check for this and cause an alarm.
|
||||
@ -44,6 +44,8 @@
|
||||
|
||||
#define MULT 1000.
|
||||
|
||||
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||
|
||||
extern "C" void shutdownCallback(void *pPvt)
|
||||
{
|
||||
pmacController *pC = static_cast<pmacController *>(pPvt);
|
||||
@ -244,6 +246,7 @@ asynStatus pmacAxis::setPosition(double position)
|
||||
{
|
||||
//int status = 0;
|
||||
static const char *functionName = "pmacAxis::setPosition";
|
||||
errlogPrintf("executing : %s\n", functionName);
|
||||
|
||||
pC_->debugFlow(functionName);
|
||||
|
||||
@ -417,6 +420,8 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
|
||||
previous_position_ = position;
|
||||
previous_direction_ = direction;
|
||||
|
||||
// errlogPrintf("Polling, axStat = %d, axErr = %d, position = %f\n", axStat, axErr, position);
|
||||
|
||||
/* are we done? */
|
||||
if((axStat == 0 || axStat == 14 || axStat < 0) && starting == 0 ){
|
||||
done = 1;
|
||||
@ -561,3 +566,122 @@ asynStatus pmacHRPTAxis::getAxisStatus(bool *moving)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*================================= SeleneAxis code ======================================================*/
|
||||
asynStatus SeleneAxis::home(double min_velocity, double max_velocity, double acceleration, int forwards)
|
||||
{
|
||||
asynStatus status = asynError;
|
||||
static const char *functionName = "SeleneAxis::home";
|
||||
|
||||
pC_->debugFlow(functionName);
|
||||
|
||||
updateMsgTxtFromDriver("Cannot home on this axis type");
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
/*----------------------------------------------------------------------------------------------------------------*/
|
||||
asynStatus SeleneAxis::move(double position, int relative, double min_velocity, double max_velocity, double acceleration)
|
||||
{
|
||||
asynStatus status = asynError;
|
||||
static const char *functionName = "SeleneAxis::move";
|
||||
double realPosition;
|
||||
|
||||
updateMsgTxtFromDriver("");
|
||||
|
||||
pC_->debugFlow(functionName);
|
||||
|
||||
char command[128] = {0};
|
||||
char response[32] = {0};
|
||||
|
||||
pC_->debugFlow(functionName);
|
||||
|
||||
if(relative){
|
||||
realPosition = previous_position_ + position/MULT;
|
||||
} else {
|
||||
realPosition = position/MULT;
|
||||
}
|
||||
startTime = time(NULL);
|
||||
status6Time = 0;
|
||||
starting = 1;
|
||||
|
||||
/*
|
||||
Run into limit when asked for by a suitable position, else
|
||||
position absolutely
|
||||
*/
|
||||
if(ABS(realPosition - limitTarget) < .05){
|
||||
sprintf(command,"P%d50=3", axisNo_);
|
||||
} else {
|
||||
sprintf(command,"Q%d51=%f P%x50=1",axisNo_, realPosition, axisNo_);
|
||||
}
|
||||
|
||||
errlogPrintf("Sending drive command: %s\n", command);
|
||||
|
||||
status = pC_->lowLevelWriteRead(axisNo_,command, response);
|
||||
|
||||
return status;
|
||||
}
|
||||
/*----------------------------------------------------------------------------------------------------*/
|
||||
asynStatus SeleneAxis::setPosition(double position) {
|
||||
asynStatus status = asynError;
|
||||
return status;
|
||||
}
|
||||
/*======================================= Selene Lift Axis Code ===========================================*/
|
||||
asynStatus LiftAxis::move(double position, int relative, double min_velocity,
|
||||
double max_velocity, double acceleration)
|
||||
{
|
||||
asynStatus status = asynError;
|
||||
static const char *functionName = "LiftAxis::move";
|
||||
double realPosition;
|
||||
|
||||
updateMsgTxtFromDriver("");
|
||||
pC_->debugFlow(functionName);
|
||||
|
||||
char command[128] = {0};
|
||||
char response[32] = {0};
|
||||
|
||||
pC_->debugFlow(functionName);
|
||||
|
||||
if(relative){
|
||||
realPosition = previous_position_ + position/MULT;
|
||||
} else {
|
||||
realPosition = position/MULT;
|
||||
}
|
||||
startTime = time(NULL);
|
||||
status6Time = 0;
|
||||
starting = 1;
|
||||
|
||||
sprintf( command, "Q15%d=%12.4f", axisNo_, realPosition);
|
||||
|
||||
status = pC_->lowLevelWriteRead(axisNo_,command, response);
|
||||
waitStart = 1;
|
||||
|
||||
return status;
|
||||
}
|
||||
/*--------------------------------------------------------------------------------------------------------
|
||||
Return *moving until the motor moved started moving. This enables the start command
|
||||
to be sent separatly.
|
||||
----------------------------------------------------------------------------------------------------------*/
|
||||
asynStatus LiftAxis::poll(bool *moving)
|
||||
{
|
||||
asynStatus status;
|
||||
|
||||
status = getAxisStatus(moving);
|
||||
if(*moving == false && waitStart == 1){
|
||||
*moving = true;
|
||||
setIntegerParam(pC_->motorStatusMoving_, true);
|
||||
setIntegerParam(pC_->motorStatusDone_, false);
|
||||
}
|
||||
if(*moving){
|
||||
waitStart = 0;
|
||||
}
|
||||
callParamCallbacks();
|
||||
return status;
|
||||
}
|
||||
/*--------------------------------------------------------------------------------------------------------------*/
|
||||
asynStatus LiftAxis::stop(double acceleration)
|
||||
{
|
||||
waitStart = 0;
|
||||
return pmacAxis::stop(acceleration);
|
||||
}
|
||||
/*-------------------------------------------------------------------------------------------------------------*/
|
||||
|
@ -10,6 +10,9 @@
|
||||
* Modified to use the MsgTxt field for SINQ
|
||||
*
|
||||
* Mark Koennecke, January 2019
|
||||
*
|
||||
* EXtended with special motor axis for the Selene
|
||||
* guide, Mark Koennecke, February 2020
|
||||
********************************************/
|
||||
|
||||
#ifndef pmacAxis_H
|
||||
@ -19,6 +22,7 @@
|
||||
#include "SINQAxis.h"
|
||||
|
||||
class pmacController;
|
||||
class SeleneController;
|
||||
|
||||
class pmacAxis : public SINQAxis
|
||||
{
|
||||
@ -76,4 +80,49 @@ class pmacHRPTAxis : public pmacAxis
|
||||
|
||||
};
|
||||
|
||||
class SeleneAxis : public pmacAxis
|
||||
{
|
||||
|
||||
public:
|
||||
SeleneAxis(SeleneController *pController, int axisNo, double limitTarget) : pmacAxis((pmacController *)pController,axisNo)
|
||||
{
|
||||
this->limitTarget = limitTarget;
|
||||
};
|
||||
asynStatus move(double position, int relative, double min_velocity, double max_velocity, double acceleration);
|
||||
asynStatus setPosition(double position);
|
||||
asynStatus home(double min_velocity, double max_velocity, double acceleration, int forwards);
|
||||
|
||||
protected:
|
||||
friend class SeleneController;
|
||||
friend class pmacController;
|
||||
|
||||
private:
|
||||
double limitTarget;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
Yet another special set of motors for the Selene Guide at AMOR. Each segment can be lifted or tilted. This is
|
||||
two motors. One acts as a slave and only writes a new target, the other also sets a new target and sends the
|
||||
actual movement command. Both motors are coordianted in the motor controller in order to avoid tension on
|
||||
the guide elements. This gaves rise to the function code LIFTSLAVE and LIFTMASTER.
|
||||
|
||||
In another mode the whole guide can be lifted or tilted. Then motor 1 and 6 get new values and one of them
|
||||
sends the drive command. This causes all 6 motors to drive synchronously to their new targets. This is
|
||||
implemented through the LIFTSEGMENT function code.
|
||||
|
||||
Mark Koennecke, February 2020
|
||||
|
||||
*/
|
||||
class LiftAxis : public pmacAxis
|
||||
{
|
||||
public:
|
||||
LiftAxis(pmacController *pController, int axisNo) : pmacAxis((pmacController *)pController,axisNo) {};
|
||||
asynStatus move(double position, int relative, double min_velocity, double max_velocity, double acceleration);
|
||||
asynStatus poll(bool *moving);
|
||||
asynStatus stop(double acceleration);
|
||||
private:
|
||||
int waitStart;
|
||||
};
|
||||
|
||||
#endif /* pmacAxis_H */
|
||||
|
@ -39,6 +39,7 @@ using std::endl;
|
||||
#include <iocsh.h>
|
||||
#include <drvSup.h>
|
||||
#include <registryFunction.h>
|
||||
#include <errlog.h>
|
||||
|
||||
#include "asynOctetSyncIO.h"
|
||||
|
||||
@ -130,6 +131,8 @@ const epicsUInt32 pmacController::PMAX_AXIS_GENERAL_PROB2 = (PMAC_STATUS2_DESIRE
|
||||
extern "C" {
|
||||
asynStatus pmacCreateController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress,
|
||||
int numAxes, int movingPollPeriod, int idlePollPeriod);
|
||||
asynStatus SeleneCreateController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress,
|
||||
int numAxes, int movingPollPeriod, int idlePollPeriod);
|
||||
|
||||
asynStatus pmacCreateAxis(const char *pmacName, int axis);
|
||||
asynStatus pmacCreateAxis(const char *pmacName, int numAxis);
|
||||
@ -137,8 +140,8 @@ extern "C" {
|
||||
}
|
||||
|
||||
pmacController::pmacController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress,
|
||||
int numAxes, double movingPollPeriod, double idlePollPeriod)
|
||||
: SINQController(portName, lowLevelPortName, numAxes+1)
|
||||
int numAxes, double movingPollPeriod, double idlePollPeriod, const int& extraParams)
|
||||
: SINQController(portName, lowLevelPortName, numAxes+1, extraParams)
|
||||
{
|
||||
static const char *functionName = "pmacController::pmacController";
|
||||
|
||||
@ -154,7 +157,7 @@ pmacController::pmacController(const char *portName, const char *lowLevelPortNam
|
||||
createParam(PMAC_C_CommsErrorString, asynParamInt32, &PMAC_C_CommsError_);
|
||||
|
||||
// Connect our Asyn user to the low level port that is a parameter to this constructor
|
||||
if (lowLevelPortConnect(lowLevelPortName, lowLevelPortAddress, &lowLevelPortUser_, "\006", "\r") != asynSuccess) {
|
||||
if (lowLevelPortConnect(lowLevelPortName, lowLevelPortAddress, &lowLevelPortUser_, "\006", (char *)"\r") != asynSuccess) {
|
||||
printf("%s: Failed to connect to low level asynOctetSyncIO port %s\n", functionName, lowLevelPortName);
|
||||
setIntegerParam(PMAC_C_CommsError_, 1);
|
||||
} else {
|
||||
@ -344,8 +347,6 @@ asynStatus pmacController::writeFloat64(asynUser *pasynUser, epicsFloat64 value)
|
||||
pmacAxis *pAxis = NULL;
|
||||
char command[64] = {0};
|
||||
char response[64] = {0};
|
||||
double encRatio = 1.0;
|
||||
epicsInt32 encposition = 0;
|
||||
char message[132];
|
||||
|
||||
static const char *functionName = "pmacController::writeFloat64";
|
||||
@ -532,6 +533,31 @@ asynStatus pmacCreateController(const char *portName, const char *lowLevelPortNa
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
asynStatus SeleneCreateController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress,
|
||||
int numAxes, int movingPollPeriod, int idlePollPeriod)
|
||||
{
|
||||
|
||||
SeleneController *ppmacController
|
||||
= new SeleneController(portName, lowLevelPortName, lowLevelPortAddress, numAxes, movingPollPeriod/1000., idlePollPeriod/1000.);
|
||||
ppmacController = NULL;
|
||||
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
|
||||
SeleneController::SeleneController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress,
|
||||
int numAxes, double movingPollPeriod, double idlePollPeriod) : pmacController(portName,
|
||||
lowLevelPortName,
|
||||
lowLevelPortAddress,
|
||||
numAxes,
|
||||
movingPollPeriod,
|
||||
idlePollPeriod, 3) {
|
||||
static const char *functionName = "seleneController::seleneController";
|
||||
createParam(MotorSetPositionString, asynParamFloat64, &setMotorPosition_);
|
||||
callParamCallbacks();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* C wrapper for the pmacAxis constructor.
|
||||
* See pmacAxis::pmacAxis.
|
||||
@ -585,6 +611,61 @@ asynStatus pmacCreateHRPTAxis(const char *pmacName, /* specify which con
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* C wrapper for the SeleneAxis constructor.
|
||||
* See SeleneAxis::SeleneAxis.
|
||||
*
|
||||
*/
|
||||
asynStatus SeleneCreateAxis(const char *pmacName, /* specify which controller by port name */
|
||||
int axis, /* axis number (start from 1). */
|
||||
double limitTarget)
|
||||
{
|
||||
SeleneController *pC;
|
||||
SeleneAxis *pAxis;
|
||||
|
||||
static const char *functionName = "SeleneCreateAxis";
|
||||
|
||||
pC = (SeleneController*) findAsynPortDriver(pmacName);
|
||||
if (!pC) {
|
||||
printf("%s:%s: Error port %s not found\n",
|
||||
driverName, functionName, pmacName);
|
||||
return asynError;
|
||||
}
|
||||
|
||||
pC->lock();
|
||||
pAxis = new SeleneAxis(pC, axis, limitTarget);
|
||||
pAxis = NULL;
|
||||
pC->unlock();
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* C wrapper for the Selene LiftAxis constructor.
|
||||
* See LiftAxis::LiftAxis.
|
||||
*
|
||||
*/
|
||||
asynStatus LiftCreateAxis(const char *pmacName, /* specify which controller by port name */
|
||||
int axis) /* axis number (start from 1). */
|
||||
{
|
||||
pmacController *pC;
|
||||
LiftAxis *pAxis;
|
||||
|
||||
static const char *functionName = "LiftCreateAxis";
|
||||
|
||||
pC = (pmacController*) findAsynPortDriver(pmacName);
|
||||
if (!pC) {
|
||||
printf("%s:%s: Error port %s not found\n",
|
||||
driverName, functionName, pmacName);
|
||||
return asynError;
|
||||
}
|
||||
|
||||
pC->lock();
|
||||
pAxis = new LiftAxis(pC, axis);
|
||||
pAxis = NULL;
|
||||
pC->unlock();
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* C Wrapper function for pmacHRPTAxis constructor.
|
||||
* See pmacAxis::pmacAxis.
|
||||
@ -617,6 +698,67 @@ asynStatus pmacCreateAxes(const char *pmacName,
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*================================ SeleneController ===============================================*/
|
||||
|
||||
asynStatus SeleneController::writeFloat64(asynUser *pasynUser, epicsFloat64 value)
|
||||
{
|
||||
int function = pasynUser->reason;
|
||||
asynStatus status = asynError;
|
||||
SeleneAxis *pAxis = NULL;
|
||||
char command[64] = {0};
|
||||
char response[64] = {0};
|
||||
char message[132];
|
||||
|
||||
static const char *functionName = "SeleneController::writeFloat64";
|
||||
|
||||
sprintf(message,"%s, reason %d", functionName, function);
|
||||
|
||||
pAxis = (SeleneAxis *)this->getAxis(pasynUser);
|
||||
if (!pAxis) {
|
||||
return asynError;
|
||||
}
|
||||
|
||||
|
||||
/* Set the parameter and readback in the parameter library. */
|
||||
status = pAxis->setDoubleParam(function, value);
|
||||
|
||||
// TODO: somethign is really shitty here: lowLimit and highLimit cannot be on the command
|
||||
if (function == motorLowLimit_) {
|
||||
sprintf(command, "Q%d54=%d", pAxis->axisNo_, (int)(value/pAxis->scale_/MULT));
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s: Setting low limit on controller %s, axis %d to %f\n",
|
||||
functionName, portName, pAxis->axisNo_, value);
|
||||
errlogPrintf("Setting low limit of axis %d to %f, command = %s\n", pAxis->axisNo_, value, command);
|
||||
} else if (function == motorHighLimit_) {
|
||||
sprintf(command, "Q%d53=%d", pAxis->axisNo_, (int)(value/pAxis->scale_/MULT));
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s: Setting high limit on controller %s, axis %d to %f\n",
|
||||
functionName, portName, pAxis->axisNo_, value);
|
||||
errlogPrintf("Setting high limit of axis %d to %f, command = %s\n", pAxis->axisNo_, value, command);
|
||||
} else if(function == setMotorPosition_){
|
||||
snprintf(command,sizeof(command),"Q%d59=%f", pAxis->axisNo_, value);
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s: Defining position of axis%d to %f\n",
|
||||
functionName, pAxis->axisNo_, value);
|
||||
errlogPrintf("Defining position of axis %d to %f, command = %s\n", pAxis->axisNo_, value, command);
|
||||
}
|
||||
|
||||
//Execute the command.
|
||||
if (command[0] != 0 && status == asynSuccess) {
|
||||
status = lowLevelWriteRead(pAxis->axisNo_,command, response);
|
||||
}
|
||||
|
||||
//Call base class method
|
||||
//This will handle callCallbacks even if the function was handled here.
|
||||
status = asynMotorController::writeFloat64(pasynUser, value);
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Code for iocsh registration */
|
||||
|
||||
#ifdef vxWorks
|
||||
@ -641,6 +783,12 @@ static void configpmacCreateControllerCallFunc(const iocshArgBuf *args)
|
||||
pmacCreateController(args[0].sval, args[1].sval, args[2].ival, args[3].ival, args[4].ival, args[5].ival);
|
||||
}
|
||||
|
||||
static const iocshFuncDef configSeleneCreateController = {"SeleneCreateController", 6, pmacCreateControllerArgs};
|
||||
static void configSeleneCreateControllerCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
SeleneCreateController(args[0].sval, args[1].sval, args[2].ival, args[3].ival, args[4].ival, args[5].ival);
|
||||
}
|
||||
|
||||
|
||||
/* pmacCreateAxis */
|
||||
static const iocshArg pmacCreateAxisArg0 = {"Controller port name", iocshArgString};
|
||||
@ -666,6 +814,34 @@ static void configpmacHRPTAxisCallFunc(const iocshArgBuf *args)
|
||||
pmacCreateHRPTAxis(args[0].sval, args[1].ival);
|
||||
}
|
||||
|
||||
|
||||
/* SeleneCreateAxis */
|
||||
static const iocshArg SeleneCreateAxisArg0 = {"Controller port name", iocshArgString};
|
||||
static const iocshArg SeleneCreateAxisArg1 = {"Axis number", iocshArgInt};
|
||||
static const iocshArg SeleneCreateAxisArg2 = {"limitTraget", iocshArgDouble};
|
||||
static const iocshArg * const SeleneCreateAxisArgs[] = {&SeleneCreateAxisArg0,
|
||||
&SeleneCreateAxisArg1,
|
||||
&SeleneCreateAxisArg2};
|
||||
static const iocshFuncDef configSeleneCreateAxis = {"SeleneCreateAxis", 3, SeleneCreateAxisArgs};
|
||||
|
||||
static void configSeleneCreateAxisCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
SeleneCreateAxis(args[0].sval, args[1].ival,args[2].dval);
|
||||
}
|
||||
|
||||
/* LiftCreateAxis */
|
||||
static const iocshArg LiftCreateAxisArg0 = {"Controller port name", iocshArgString};
|
||||
static const iocshArg LiftCreateAxisArg1 = {"Axis number", iocshArgInt};
|
||||
static const iocshArg * const LiftCreateAxisArgs[] = {&LiftCreateAxisArg0,
|
||||
&LiftCreateAxisArg1};
|
||||
static const iocshFuncDef configLiftAxis = {"LiftCreateAxis", 2, LiftCreateAxisArgs};
|
||||
|
||||
static void configLiftAxisCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
LiftCreateAxis(args[0].sval, args[1].ival);
|
||||
}
|
||||
|
||||
|
||||
/* pmacCreateAxes */
|
||||
static const iocshArg pmacCreateAxesArg0 = {"Controller port name", iocshArgString};
|
||||
static const iocshArg pmacCreateAxesArg1 = {"Num Axes", iocshArgInt};
|
||||
@ -683,8 +859,11 @@ static void configpmacAxesCallFunc(const iocshArgBuf *args)
|
||||
static void pmacControllerRegister(void)
|
||||
{
|
||||
iocshRegister(&configpmacCreateController, configpmacCreateControllerCallFunc);
|
||||
iocshRegister(&configSeleneCreateController, configSeleneCreateControllerCallFunc);
|
||||
iocshRegister(&configpmacAxis, configpmacAxisCallFunc);
|
||||
iocshRegister(&configpmacHRPTAxis, configpmacHRPTAxisCallFunc);
|
||||
iocshRegister(&configSeleneCreateAxis, configSeleneCreateAxisCallFunc);
|
||||
iocshRegister(&configLiftAxis, configLiftAxisCallFunc);
|
||||
iocshRegister(&configpmacAxes, configpmacAxesCallFunc);
|
||||
}
|
||||
epicsExportRegistrar(pmacControllerRegister);
|
||||
@ -693,3 +872,4 @@ epicsExportRegistrar(pmacControllerRegister);
|
||||
|
||||
} // extern "C"
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ class pmacController : public SINQController {
|
||||
|
||||
public:
|
||||
pmacController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress, int numAxes, double movingPollPeriod,
|
||||
double idlePollPeriod);
|
||||
double idlePollPeriod, const int& extraParams=2);
|
||||
|
||||
virtual ~pmacController();
|
||||
|
||||
@ -49,13 +49,13 @@ class pmacController : public SINQController {
|
||||
int PMAC_C_GlobalStatus_;
|
||||
int PMAC_C_CommsError_;
|
||||
#define LAST_PMAC_PARAM PMAC_C_CommsError__
|
||||
void debugFlow(const char *message);
|
||||
asynStatus lowLevelWriteRead(int axisNo, const char *command, char *response);
|
||||
|
||||
private:
|
||||
asynUser* lowLevelPortUser_;
|
||||
epicsUInt32 debugFlag_;
|
||||
asynStatus lowLevelWriteRead(int axisNo, const char *command, char *response);
|
||||
int lowLevelPortConnect(const char *port, int addr, asynUser **ppasynUser, char *inputEos, char *outputEos);
|
||||
void debugFlow(const char *message);
|
||||
|
||||
//static class data members
|
||||
|
||||
@ -137,9 +137,31 @@ class pmacController : public SINQController {
|
||||
|
||||
friend class pmacAxis;
|
||||
friend class pmacHRPTAxis;
|
||||
|
||||
friend class SeleneAxis;
|
||||
friend class LiftAxis;
|
||||
};
|
||||
|
||||
#define NUM_PMAC_PARAMS (&LAST_PMAC_PARAM - &FIRST_PMAC_PARAM + 1)
|
||||
|
||||
#define MotorSetPositionString "SET_MOTOR_POSITION"
|
||||
|
||||
class SeleneController : public pmacController {
|
||||
public:
|
||||
SeleneController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress,
|
||||
int numAxes, double movingPollPeriod, double idlePollPeriod);
|
||||
|
||||
~SeleneController(void) { }
|
||||
|
||||
// overloaded because we have a different command to set the limits
|
||||
asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
|
||||
|
||||
friend class SeleneAxis;
|
||||
friend class pmacAxis;
|
||||
|
||||
protected:
|
||||
int setMotorPosition_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* pmacController_H */
|
||||
|
Reference in New Issue
Block a user