Current draft for the detector axis tower driver
This commit is contained in:
+130
-68
@@ -1,6 +1,8 @@
|
||||
#include "detectorTowerController.h"
|
||||
#include "detectorTowerAxis.h"
|
||||
#include "turboPmacController.h"
|
||||
#include <epicsExport.h>
|
||||
#include <errlog.h>
|
||||
#include <iocsh.h>
|
||||
|
||||
/**
|
||||
@@ -38,6 +40,17 @@ detectorTowerController::detectorTowerController(
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
status =
|
||||
createParam("LIFT_OFFSET_MOVE", asynParamFloat64, &liftOffsetMove_);
|
||||
if (status != asynSuccess) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
||||
"parameter failed with %s).\nTerminating IOC",
|
||||
portName, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
status = createParam("LIFT_OFFSET_LOW_LIMIT", asynParamFloat64,
|
||||
&liftOffsetLowLimit_);
|
||||
if (status != asynSuccess) {
|
||||
@@ -70,6 +83,17 @@ detectorTowerController::detectorTowerController(
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
status =
|
||||
createParam("TILT_OFFSET_MOVE", asynParamFloat64, &tiltOffsetMove_);
|
||||
if (status != asynSuccess) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
||||
"parameter failed with %s).\nTerminating IOC",
|
||||
portName, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
status = createParam("TILT_OFFSET_LOW_LIMIT", asynParamFloat64,
|
||||
&tiltOffsetLowLimit_);
|
||||
if (status != asynSuccess) {
|
||||
@@ -92,6 +116,16 @@ detectorTowerController::detectorTowerController(
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
status = createParam("BEAM_ANGLE", asynParamFloat64, &beamAngle_);
|
||||
if (status != asynSuccess) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
||||
"parameter failed with %s).\nTerminating IOC",
|
||||
portName, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
status = createParam("POSITION_STATE", asynParamInt32, &positionState_);
|
||||
if (status != asynSuccess) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
@@ -102,7 +136,28 @@ detectorTowerController::detectorTowerController(
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
status = createParam("RESET", asynParamInt32, &reset_);
|
||||
status = createParam("START", asynParamInt32, &start_);
|
||||
if (status != asynSuccess) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
||||
"parameter failed with %s).\nTerminating IOC",
|
||||
portName, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
status = createParam("MOVE_TO_WORKING_POSITION", asynParamInt32,
|
||||
&moveToWorkingPosition_);
|
||||
if (status != asynSuccess) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
||||
"parameter failed with %s).\nTerminating IOC",
|
||||
portName, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
status = createParam("RESET_ERROR", asynParamInt32, &resetError_);
|
||||
if (status != asynSuccess) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
||||
@@ -115,12 +170,20 @@ detectorTowerController::detectorTowerController(
|
||||
|
||||
asynStatus detectorTowerController::readInt32(asynUser *pasynUser,
|
||||
epicsInt32 *value) {
|
||||
// The detector tower cannot be disabled
|
||||
if (pasynUser->reason == motorCanDisable_) {
|
||||
*value = 0;
|
||||
return asynSuccess;
|
||||
} else {
|
||||
|
||||
// Check if the axis is a detectorTowerAxis
|
||||
detectorTowerAxis *axis = getDetectorTowerAxis(pasynUser);
|
||||
if (axis == nullptr) {
|
||||
// This is apparently a "normal" turboPmacAxis
|
||||
return turboPmacController::readInt32(pasynUser, value);
|
||||
} else {
|
||||
// The detector tower cannot be disabled
|
||||
if (pasynUser->reason == motorCanDisable_) {
|
||||
*value = 0;
|
||||
return asynSuccess;
|
||||
} else {
|
||||
return turboPmacController::readInt32(pasynUser, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,22 +193,40 @@ asynStatus detectorTowerController::writeInt32(asynUser *pasynUser,
|
||||
|
||||
// =====================================================================
|
||||
|
||||
detectorTowerAxis *axis = getVirtualAxis(pasynUser);
|
||||
if (axis == nullptr) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d:\nAxis is not an "
|
||||
"instance of sinqAxis",
|
||||
portName, axis->axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
return asynError;
|
||||
}
|
||||
detectorTowerAxis *axis = getDetectorTowerAxis(pasynUser);
|
||||
|
||||
// Handle custom PVs
|
||||
if (function == motorEnable_) {
|
||||
return axis->enable(value);
|
||||
} else if (function == reset_) {
|
||||
return axis->reset();
|
||||
} else {
|
||||
if (axis == nullptr) {
|
||||
// This is apparently a "normal" turboPmacAxis
|
||||
return turboPmacController::writeInt32(pasynUser, value);
|
||||
} else {
|
||||
// Handle custom PVs
|
||||
if (function == start_) {
|
||||
|
||||
// Start the movement, if the axis is not already moving.
|
||||
// Otherwise stop it and schedule a movement.
|
||||
int done = 0;
|
||||
asynStatus status =
|
||||
getIntegerParam(axis->axisNo_, motorStatusDone_, &done);
|
||||
if (status != asynSuccess) {
|
||||
return paramLibAccessFailed(status, "motorStatusDone_",
|
||||
axis->axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
if (done == 1) {
|
||||
return axis->moveFromParamLib();
|
||||
} else {
|
||||
axis->scheduleMoveFromParamLib_ = true;
|
||||
return axis->stop(0.0);
|
||||
}
|
||||
|
||||
} else if (function == moveToWorkingPosition_) {
|
||||
return axis->moveToWorkingPosition(value != 0);
|
||||
} else if (function == resetError_) {
|
||||
return axis->reset();
|
||||
} else {
|
||||
return turboPmacController::writeInt32(pasynUser, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,30 +234,33 @@ asynStatus detectorTowerController::writeFloat64(asynUser *pasynUser,
|
||||
epicsFloat64 value) {
|
||||
int function = pasynUser->reason;
|
||||
|
||||
// =====================================================================
|
||||
detectorTowerAxis *axis = getDetectorTowerAxis(pasynUser);
|
||||
|
||||
detectorTowerAxis *axis = getVirtualAxis(pasynUser);
|
||||
if (axis == nullptr) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d:\nAxis is not an "
|
||||
"instance of sinqAxis",
|
||||
portName, axis->axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
return asynError;
|
||||
}
|
||||
|
||||
if (function == motorTargetPosition_) {
|
||||
// Start the movement, if the axis is not already moving. Otherwise stop
|
||||
// it and schedule a movement.
|
||||
bool moving = false;
|
||||
axis->poll(&moving);
|
||||
if (moving) {
|
||||
axis->scheduleMoveFromParamLib_ = true;
|
||||
return axis->stop(0.0);
|
||||
} else {
|
||||
return axis->moveFromParamLib();
|
||||
}
|
||||
} else {
|
||||
// This is apparently a "normal" turboPmacAxis
|
||||
return turboPmacController::writeFloat64(pasynUser, value);
|
||||
} else {
|
||||
if (function == liftOffsetMove_) {
|
||||
asynStatus status =
|
||||
setDoubleParam(axis->axisNo_, liftOffset_, value);
|
||||
if (status != asynSuccess) {
|
||||
return paramLibAccessFailed(status, "liftOffset_",
|
||||
axis->axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
return axis->moveFromParamLib();
|
||||
} else if (function == tiltOffsetMove_) {
|
||||
asynStatus status =
|
||||
setDoubleParam(axis->axisNo_, tiltOffset_, value);
|
||||
if (status != asynSuccess) {
|
||||
return paramLibAccessFailed(status, "tiltOffset_",
|
||||
axis->axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
return axis->moveFromParamLib();
|
||||
} else {
|
||||
return turboPmacController::writeFloat64(pasynUser, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,40 +270,18 @@ If the axis does not exist or is not a Axis, a nullptr is returned and an
|
||||
error is emitted.
|
||||
*/
|
||||
detectorTowerAxis *
|
||||
detectorTowerController::getVirtualAxis(asynUser *pasynUser) {
|
||||
detectorTowerController::getDetectorTowerAxis(asynUser *pasynUser) {
|
||||
asynMotorAxis *asynAxis = asynMotorController::getAxis(pasynUser);
|
||||
return detectorTowerController::castToVirtualAxis(asynAxis);
|
||||
return dynamic_cast<detectorTowerAxis *>(asynAxis);
|
||||
}
|
||||
|
||||
/*
|
||||
Access one of the axes of the controller via the axis index.
|
||||
If the axis does not exist or is not a Axis, the function must return Null
|
||||
*/
|
||||
detectorTowerAxis *detectorTowerController::getVirtualAxis(int axisNo) {
|
||||
detectorTowerAxis *detectorTowerController::getDetectorTowerAxis(int axisNo) {
|
||||
asynMotorAxis *asynAxis = asynMotorController::getAxis(axisNo);
|
||||
return detectorTowerController::castToVirtualAxis(asynAxis);
|
||||
}
|
||||
|
||||
detectorTowerAxis *
|
||||
detectorTowerController::castToVirtualAxis(asynMotorAxis *asynAxis) {
|
||||
|
||||
// =========================================================================
|
||||
|
||||
// If the axis slot of the pAxes_ array is empty, a nullptr must be returned
|
||||
if (asynAxis == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Here, an error is emitted since asyn_axis is not a nullptr but also not
|
||||
// an instance of Axis
|
||||
detectorTowerAxis *axis = dynamic_cast<detectorTowerAxis *>(asynAxis);
|
||||
if (axis == nullptr) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is not "
|
||||
"an instance of turboPmacAxis",
|
||||
portName, axis->axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
return axis;
|
||||
return dynamic_cast<detectorTowerAxis *>(asynAxis);
|
||||
}
|
||||
|
||||
/*************************************************************************************/
|
||||
@@ -292,4 +354,4 @@ static void detectorTowerControllerRegister(void) {
|
||||
}
|
||||
epicsExportRegistrar(detectorTowerControllerRegister);
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
|
||||
Reference in New Issue
Block a user