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:
michele-brambilla
2020-02-17 11:10:02 +01:00
parent 3b7133ecfe
commit c4fe45c0cb
8 changed files with 411 additions and 27 deletions

View File

@ -25,17 +25,20 @@ TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
#SNCSEQ=$(EPICS_BASE)/../modules/soft/seq #SNCSEQ=$(EPICS_BASE)/../modules/soft/seq
# EPICS_BASE usually appears last so other apps can override stuff: # 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 # Set RULES here if you want to take build rules from somewhere
# other than EPICS_BASE: # other than EPICS_BASE:
#RULES=/path/to/epics/support/module/rules/x-y ##RULES=/path/to/epics/support/module/rules/x-y
MOTOR=/opt/epics/modules/motor/6.10.0/3.14.12.5 #MOTOR=/opt/epics/modules/motor/6.10.0/3.14.12.5
ASYN=/opt/epics/modules/asyn/4.27.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/ #SYNAPPSSTD=/opt/epics/modules/synAppsStd/3.4.1/3.14.12.5/
#ANC=/usr/local/epics/anc350v17 ##ANC=/usr/local/epics/anc350v17
STREAMS=/opt/epics/modules/streamdevice/2.6.0/3.14.12.5 #STREAMS=/opt/epics/modules/streamdevice/2.6.0/3.14.12.5
#LAKESHORE336=/usr/local/epics/support/lakeshore336 ##LAKESHORE336=/usr/local/epics/support/lakeshore336
BUSY=/opt/epics/modules/busy/1.6.0/3.14.12.5 #BUSY=/opt/epics/modules/busy/1.6.0/3.14.12.5
#OXINSTCRYOJET=/usr/local/epics/support/OxInstCryojet-2-18-3 ##OXINSTCRYOJET=/usr/local/epics/support/OxInstCryojet-2-18-3
PCRE=/opt/epics/modules/pcre/8.36.0/3.14.12.5 #PCRE=/opt/epics/modules/pcre/8.36.0/3.14.12.5

View 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")
}

View File

@ -10,8 +10,8 @@
#include "SINQController.h" #include "SINQController.h"
#include "asynMotorController.h" #include "asynMotorController.h"
SINQController::SINQController(const char *portName, const char *SINQPortName, int numAxes) SINQController::SINQController(const char *portName, const char *SINQPortName, int numAxes, const int& extraParams)
: asynMotorController(portName, numAxes+1, NUM_MOTOR_DRIVER_PARAMS+2, : asynMotorController(portName, numAxes+1, NUM_MOTOR_DRIVER_PARAMS+extraParams,
0, // No additional interfaces beyond those in base class 0, // No additional interfaces beyond those in base class
0, // No additional callback interfaces beyond those in base class 0, // No additional callback interfaces beyond those in base class
ASYN_CANBLOCK | ASYN_MULTIDEVICE, ASYN_CANBLOCK | ASYN_MULTIDEVICE,

View File

@ -17,7 +17,7 @@
class epicsShareClass SINQController : public asynMotorController class epicsShareClass SINQController : public asynMotorController
{ {
public: 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; friend class SINQAxis;
protected: protected:

View File

@ -8,9 +8,9 @@
* 23 May 2012 * 23 May 2012
* *
* Substantially modified for use at SINQ at PSI. * 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. * 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: * 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. * when the motor is hung, it wont start. I check for this and cause an alarm.
@ -44,6 +44,8 @@
#define MULT 1000. #define MULT 1000.
#define ABS(x) (x < 0 ? -(x) : (x))
extern "C" void shutdownCallback(void *pPvt) extern "C" void shutdownCallback(void *pPvt)
{ {
pmacController *pC = static_cast<pmacController *>(pPvt); pmacController *pC = static_cast<pmacController *>(pPvt);
@ -244,7 +246,8 @@ asynStatus pmacAxis::setPosition(double position)
{ {
//int status = 0; //int status = 0;
static const char *functionName = "pmacAxis::setPosition"; static const char *functionName = "pmacAxis::setPosition";
errlogPrintf("executing : %s\n", functionName);
pC_->debugFlow(functionName); pC_->debugFlow(functionName);
// Cannot do this. // Cannot do this.
@ -417,6 +420,8 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
previous_position_ = position; previous_position_ = position;
previous_direction_ = direction; previous_direction_ = direction;
// errlogPrintf("Polling, axStat = %d, axErr = %d, position = %f\n", axStat, axErr, position);
/* are we done? */ /* are we done? */
if((axStat == 0 || axStat == 14 || axStat < 0) && starting == 0 ){ if((axStat == 0 || axStat == 14 || axStat < 0) && starting == 0 ){
done = 1; done = 1;
@ -561,3 +566,122 @@ asynStatus pmacHRPTAxis::getAxisStatus(bool *moving)
} }
return result; 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);
}
/*-------------------------------------------------------------------------------------------------------------*/

View File

@ -10,6 +10,9 @@
* Modified to use the MsgTxt field for SINQ * Modified to use the MsgTxt field for SINQ
* *
* Mark Koennecke, January 2019 * Mark Koennecke, January 2019
*
* EXtended with special motor axis for the Selene
* guide, Mark Koennecke, February 2020
********************************************/ ********************************************/
#ifndef pmacAxis_H #ifndef pmacAxis_H
@ -19,6 +22,7 @@
#include "SINQAxis.h" #include "SINQAxis.h"
class pmacController; class pmacController;
class SeleneController;
class pmacAxis : public SINQAxis 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 */ #endif /* pmacAxis_H */

View File

@ -39,6 +39,7 @@ using std::endl;
#include <iocsh.h> #include <iocsh.h>
#include <drvSup.h> #include <drvSup.h>
#include <registryFunction.h> #include <registryFunction.h>
#include <errlog.h>
#include "asynOctetSyncIO.h" #include "asynOctetSyncIO.h"
@ -130,6 +131,8 @@ const epicsUInt32 pmacController::PMAX_AXIS_GENERAL_PROB2 = (PMAC_STATUS2_DESIRE
extern "C" { extern "C" {
asynStatus pmacCreateController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress, asynStatus pmacCreateController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress,
int numAxes, int movingPollPeriod, int idlePollPeriod); 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 axis);
asynStatus pmacCreateAxis(const char *pmacName, int numAxis); asynStatus pmacCreateAxis(const char *pmacName, int numAxis);
@ -137,8 +140,8 @@ extern "C" {
} }
pmacController::pmacController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress, pmacController::pmacController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress,
int numAxes, double movingPollPeriod, double idlePollPeriod) int numAxes, double movingPollPeriod, double idlePollPeriod, const int& extraParams)
: SINQController(portName, lowLevelPortName, numAxes+1) : SINQController(portName, lowLevelPortName, numAxes+1, extraParams)
{ {
static const char *functionName = "pmacController::pmacController"; 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_); createParam(PMAC_C_CommsErrorString, asynParamInt32, &PMAC_C_CommsError_);
// Connect our Asyn user to the low level port that is a parameter to this constructor // 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); printf("%s: Failed to connect to low level asynOctetSyncIO port %s\n", functionName, lowLevelPortName);
setIntegerParam(PMAC_C_CommsError_, 1); setIntegerParam(PMAC_C_CommsError_, 1);
} else { } else {
@ -344,8 +347,6 @@ asynStatus pmacController::writeFloat64(asynUser *pasynUser, epicsFloat64 value)
pmacAxis *pAxis = NULL; pmacAxis *pAxis = NULL;
char command[64] = {0}; char command[64] = {0};
char response[64] = {0}; char response[64] = {0};
double encRatio = 1.0;
epicsInt32 encposition = 0;
char message[132]; char message[132];
static const char *functionName = "pmacController::writeFloat64"; static const char *functionName = "pmacController::writeFloat64";
@ -532,6 +533,31 @@ asynStatus pmacCreateController(const char *portName, const char *lowLevelPortNa
return asynSuccess; 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. * C wrapper for the pmacAxis constructor.
* See pmacAxis::pmacAxis. * See pmacAxis::pmacAxis.
@ -585,6 +611,61 @@ asynStatus pmacCreateHRPTAxis(const char *pmacName, /* specify which con
return asynSuccess; 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. * C Wrapper function for pmacHRPTAxis constructor.
* See pmacAxis::pmacAxis. * See pmacAxis::pmacAxis.
@ -617,6 +698,67 @@ asynStatus pmacCreateAxes(const char *pmacName,
return asynSuccess; 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 */ /* Code for iocsh registration */
#ifdef vxWorks #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); 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 */ /* pmacCreateAxis */
static const iocshArg pmacCreateAxisArg0 = {"Controller port name", iocshArgString}; 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); 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 */ /* pmacCreateAxes */
static const iocshArg pmacCreateAxesArg0 = {"Controller port name", iocshArgString}; static const iocshArg pmacCreateAxesArg0 = {"Controller port name", iocshArgString};
static const iocshArg pmacCreateAxesArg1 = {"Num Axes", iocshArgInt}; static const iocshArg pmacCreateAxesArg1 = {"Num Axes", iocshArgInt};
@ -683,8 +859,11 @@ static void configpmacAxesCallFunc(const iocshArgBuf *args)
static void pmacControllerRegister(void) static void pmacControllerRegister(void)
{ {
iocshRegister(&configpmacCreateController, configpmacCreateControllerCallFunc); iocshRegister(&configpmacCreateController, configpmacCreateControllerCallFunc);
iocshRegister(&configSeleneCreateController, configSeleneCreateControllerCallFunc);
iocshRegister(&configpmacAxis, configpmacAxisCallFunc); iocshRegister(&configpmacAxis, configpmacAxisCallFunc);
iocshRegister(&configpmacHRPTAxis, configpmacHRPTAxisCallFunc); iocshRegister(&configpmacHRPTAxis, configpmacHRPTAxisCallFunc);
iocshRegister(&configSeleneCreateAxis, configSeleneCreateAxisCallFunc);
iocshRegister(&configLiftAxis, configLiftAxisCallFunc);
iocshRegister(&configpmacAxes, configpmacAxesCallFunc); iocshRegister(&configpmacAxes, configpmacAxesCallFunc);
} }
epicsExportRegistrar(pmacControllerRegister); epicsExportRegistrar(pmacControllerRegister);
@ -693,3 +872,4 @@ epicsExportRegistrar(pmacControllerRegister);
} // extern "C" } // extern "C"

View File

@ -26,8 +26,8 @@
class pmacController : public SINQController { class pmacController : public SINQController {
public: public:
pmacController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress, int numAxes, double movingPollPeriod, pmacController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress, int numAxes, double movingPollPeriod,
double idlePollPeriod); double idlePollPeriod, const int& extraParams=2);
virtual ~pmacController(); virtual ~pmacController();
@ -49,13 +49,13 @@ class pmacController : public SINQController {
int PMAC_C_GlobalStatus_; int PMAC_C_GlobalStatus_;
int PMAC_C_CommsError_; int PMAC_C_CommsError_;
#define LAST_PMAC_PARAM 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: private:
asynUser* lowLevelPortUser_; asynUser* lowLevelPortUser_;
epicsUInt32 debugFlag_; epicsUInt32 debugFlag_;
asynStatus lowLevelWriteRead(int axisNo, const char *command, char *response);
int lowLevelPortConnect(const char *port, int addr, asynUser **ppasynUser, char *inputEos, char *outputEos); int lowLevelPortConnect(const char *port, int addr, asynUser **ppasynUser, char *inputEos, char *outputEos);
void debugFlow(const char *message);
//static class data members //static class data members
@ -137,9 +137,31 @@ class pmacController : public SINQController {
friend class pmacAxis; friend class pmacAxis;
friend class pmacHRPTAxis; friend class pmacHRPTAxis;
friend class SeleneAxis;
friend class LiftAxis;
}; };
#define NUM_PMAC_PARAMS (&LAST_PMAC_PARAM - &FIRST_PMAC_PARAM + 1) #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 */ #endif /* pmacController_H */