- Fixed a enable PV initialisation bug in MasterMACS
- Made the HRPT axis base itself on V3 of the pmacAxis - Improved and added utils programs
This commit is contained in:
@ -4,6 +4,7 @@
|
||||
Marcel Schildt
|
||||
|
||||
Mark Koennecke, March-August 2023
|
||||
Mark Koenencke, More fixes in June 2024
|
||||
*/
|
||||
|
||||
|
||||
@ -13,6 +14,7 @@
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iocsh.h>
|
||||
@ -28,6 +30,18 @@
|
||||
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||
|
||||
#define debug 0
|
||||
#define timeDebug 0
|
||||
|
||||
double DoubleTime(void)
|
||||
{
|
||||
struct timeval now;
|
||||
/* the resolution of this function is usec, if the machine supports this
|
||||
and the mantissa of a double is 51 bits or more (31 bits for seconds
|
||||
and 20 for microseconds)
|
||||
*/
|
||||
gettimeofday(&now, NULL);
|
||||
return now.tv_sec + now.tv_usec / 1e6;
|
||||
}
|
||||
|
||||
/** Creates a new MasterMACSController object.
|
||||
* \param[in] portName The name of the asyn port that will be created for this driver
|
||||
@ -141,6 +155,7 @@ asynStatus
|
||||
size_t in, out;
|
||||
int reason, len, idx, lenPayload;
|
||||
unsigned int i;
|
||||
double startTime, now;
|
||||
char *mmacsData =
|
||||
NULL, ackchar, mmacsResponse[COMLEN], hexResponse[256];
|
||||
SINQAxis *axis = getAxis(axisNo);
|
||||
@ -173,10 +188,19 @@ asynStatus
|
||||
errlogSevPrintf(errlogMajor,"Sending command: %s\n", command);
|
||||
}
|
||||
|
||||
startTime = DoubleTime();
|
||||
status =
|
||||
pasynOctetSyncIO->writeRead(pasynUserController_, mmacsData,
|
||||
len - 1, mmacsResponse, 35, 5., &out,
|
||||
len - 1, mmacsResponse, 35, 10., &out,
|
||||
&in, &reason);
|
||||
|
||||
if(timeDebug) {
|
||||
now = DoubleTime();
|
||||
if((now - startTime) > 1.) {
|
||||
errlogSevPrintf(errlogMajor, "Unusual response time %lf to command %s\n", (now - startTime), command);
|
||||
}
|
||||
}
|
||||
|
||||
if (status != asynSuccess) {
|
||||
if (axis != NULL) {
|
||||
errlogSevPrintf(errlogMajor,
|
||||
@ -247,6 +271,34 @@ asynStatus
|
||||
return status;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------------*/
|
||||
asynStatus
|
||||
MasterMACSController::readInt32(asynUser * pasynUser,
|
||||
epicsInt32 * value)
|
||||
{
|
||||
|
||||
int function = pasynUser->reason;
|
||||
MasterMACSAxis *pAxis = NULL;
|
||||
int devStatus, isOn;
|
||||
|
||||
pAxis = (MasterMACSAxis *) (this->getAxis(pasynUser));
|
||||
if (!pAxis) {
|
||||
return asynError;
|
||||
}
|
||||
if (function == axisEnabled_) {
|
||||
devStatus = pAxis->readStatus();
|
||||
isOn = pAxis->isOn(devStatus);
|
||||
// errlogPrintf("isOn in readInt32: %d, devStatus = %d\n", isOn, devStatus);
|
||||
pAxis->setIntegerParam(enableAxis_, isOn);
|
||||
pAxis->setIntegerParam(axisEnabled_, isOn);
|
||||
*value = isOn;
|
||||
callParamCallbacks();
|
||||
return asynSuccess;
|
||||
}
|
||||
return asynMotorController::readInt32(pasynUser, value);
|
||||
}
|
||||
/*------------------------------------------------------------------------------------------*/
|
||||
|
||||
asynStatus
|
||||
MasterMACSController::writeInt32(asynUser * pasynUser,
|
||||
epicsInt32 value)
|
||||
@ -305,10 +357,14 @@ asynStatus
|
||||
errlogPrintf("MMACS: Failure to enable or disable axis %d",
|
||||
pAxis->axisNo_);
|
||||
}
|
||||
/*
|
||||
* wait max 2 seconds for success of the operation
|
||||
*/
|
||||
startTime = time(NULL);
|
||||
while(time(NULL) < startTime + 2.){
|
||||
// wait for the change to happen
|
||||
devStatus = pAxis->readStatus();
|
||||
// errlogPrintf("MMACS: switching enable: target, devStatus, isOn: %d, %d, %d\n", value, devStatus, pAxis->isOn(devStatus));
|
||||
if(pAxis->isOn(devStatus) == value){
|
||||
pAxis->active = true;
|
||||
pAxis->poll(&moving); // to update the Enable_RBV field
|
||||
@ -317,7 +373,7 @@ asynStatus
|
||||
}
|
||||
usleep(200);
|
||||
}
|
||||
errlogPrintf("MMACS: Failed to enable motor %d within 2 seconds\n", pAxis->axisNo_);
|
||||
errlogPrintf("MMACS: Failed to dis/enable motor %d within 2 seconds\n", pAxis->axisNo_);
|
||||
}
|
||||
return asynMotorController::writeInt32(pasynUser, value);
|
||||
}
|
||||
@ -332,11 +388,17 @@ asynStatus
|
||||
* Initializes register numbers, etc.
|
||||
*/
|
||||
MasterMACSAxis::MasterMACSAxis(MasterMACSController * pC, int axisNo):SINQAxis(pC, axisNo),
|
||||
pC_
|
||||
(pC)
|
||||
pC_(pC)
|
||||
{
|
||||
hasStarted = false;
|
||||
active = false;
|
||||
errorCodeFound = 0;
|
||||
/*
|
||||
* Try to read the initial enable status of the motor
|
||||
*/
|
||||
int devStatus = readStatus();
|
||||
setIntegerParam(pC_->enableAxis_, isOn(devStatus));
|
||||
setIntegerParam(pC_->axisEnabled_, isOn(devStatus));
|
||||
}
|
||||
|
||||
/** Reports on status of the axis
|
||||
@ -361,7 +423,7 @@ int MasterMACSAxis::readStatus()
|
||||
/*
|
||||
* The MasterMACS sends invalid responses with a low frequency.
|
||||
* Therefore I send cached status responses in such a case in order
|
||||
* to help the logic evrywhere else in the code.
|
||||
* to help the logic everywhere else in the code.
|
||||
*/
|
||||
sprintf(command, "%dR10", axisNo_);
|
||||
status = pC_->transactController(axisNo_, command, reply);
|
||||
@ -548,7 +610,7 @@ asynStatus MasterMACSAxis::poll(bool * moving)
|
||||
{
|
||||
asynStatus comStatus = asynSuccess;
|
||||
char command[COMLEN], reply[COMLEN], *pPtr, buffer[80];
|
||||
unsigned int errCode, derCode, devStatus;
|
||||
unsigned int errCode, derCode, devStatus = 0;
|
||||
float errStatus;
|
||||
struct tm* tm_info;
|
||||
time_t timer;
|
||||
@ -599,7 +661,7 @@ asynStatus MasterMACSAxis::poll(bool * moving)
|
||||
|
||||
// Read the overall status of this motor */
|
||||
devStatus = readStatus();
|
||||
if(debug) {
|
||||
if(debug || timeDebug) {
|
||||
errlogPrintf("Axis %d, position %lf, devStatus %d\n", axisNo_,
|
||||
position, devStatus);
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ public:
|
||||
MasterMACSAxis* getAxis(int axisNo);
|
||||
|
||||
// overloaded because we want to enable/disable the motor
|
||||
asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
|
||||
asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
|
||||
|
||||
friend class MasterMACSAxis;
|
||||
|
@ -596,7 +596,7 @@ asynStatus pmacHRPTAxis::getAxisStatus(bool *moving) {
|
||||
char response[pC_->PMAC_MAXBUF_];
|
||||
int cmdStatus = 0, nvals, crashSignal;
|
||||
|
||||
asynStatus result = pmacAxis::getAxisStatus(moving);
|
||||
asynStatus result = pmacV3Axis::getAxisStatus(moving);
|
||||
sprintf(command, "P%2.2d53", axisNo_);
|
||||
cmdStatus = pC_->lowLevelWriteRead(axisNo_, command, response);
|
||||
nvals = sscanf(response, "%d", &crashSignal);
|
||||
|
@ -70,22 +70,6 @@ protected:
|
||||
friend class pmacController;
|
||||
friend class pmacV3Controller;
|
||||
};
|
||||
/*----------------------------------------------------------------------------------------------*/
|
||||
class pmacHRPTAxis : public pmacAxis
|
||||
{
|
||||
public:
|
||||
pmacHRPTAxis(pmacController *pController, int axisNo) : pmacAxis(pController,axisNo) {};
|
||||
/**
|
||||
* Override getAxisStatus in order to read the special parameter indicating a
|
||||
* slit blade crash at HRPT
|
||||
*/
|
||||
asynStatus getAxisStatus(bool *moving);
|
||||
|
||||
protected:
|
||||
friend class pmacController;
|
||||
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------------------------*/
|
||||
class SeleneAxis : public pmacAxis
|
||||
{
|
||||
@ -157,6 +141,23 @@ public:
|
||||
friend class pmacV3Controller;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------------------------*/
|
||||
class pmacHRPTAxis : public pmacV3Axis
|
||||
{
|
||||
public:
|
||||
pmacHRPTAxis(pmacController *pController, int axisNo) : pmacV3Axis(pController,axisNo) {};
|
||||
/**
|
||||
* Override getAxisStatus in order to read the special parameter indicating a
|
||||
* slit blade crash at HRPT
|
||||
*/
|
||||
asynStatus getAxisStatus(bool *moving);
|
||||
|
||||
protected:
|
||||
friend class pmacController;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Special motors for the AMOR detector movement. The whole
|
||||
* command set is different but on a pmac controller. This implements
|
||||
|
@ -869,10 +869,14 @@ static const char *functionName = "pmacV3Controller::writeInt32";
|
||||
snprintf(command, sizeof(command), "P%2.2d00", pAxis->axisNo_);
|
||||
this->lowLevelWriteRead(pAxis->axisNo_, command, response);
|
||||
isOn = strtol(response, NULL, 10) != -3;
|
||||
/* This was an attempt at automatically reading the encoder.
|
||||
This is disabled as it did not work.
|
||||
*/
|
||||
if(value == 1 && isOn) {
|
||||
sprintf(command, "M%2.2d=15", pAxis->axisNo_);
|
||||
// lowLevelWriteRead(pAxis->axisNo_, command, response);
|
||||
}
|
||||
// Valid code continues here
|
||||
sprintf(command, "M%2.2d14=%d", pAxis->axisNo_, value);
|
||||
pAxis->updateMsgTxtFromDriver("");
|
||||
if(isOn != value) {
|
||||
|
Reference in New Issue
Block a user