Final version of the SINQ EPICS module for RHEL7 in 2023
- Fixes to MasterMACS, mostly. - Minor changes
This commit is contained in:
@ -2,7 +2,6 @@
|
|||||||
include /ioc/tools/driver.makefile
|
include /ioc/tools/driver.makefile
|
||||||
|
|
||||||
MODULE=sinq
|
MODULE=sinq
|
||||||
LIBVERSION=koennecke
|
|
||||||
BUILDCLASSES=Linux
|
BUILDCLASSES=Linux
|
||||||
EPICS_VERSIONS=3.14.12 7.0.4.1
|
EPICS_VERSIONS=3.14.12 7.0.4.1
|
||||||
|
|
||||||
|
48
sinqEPICSApp/Db/sinq_asyn_motor.db
Normal file
48
sinqEPICSApp/Db/sinq_asyn_motor.db
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
record(motor,"$(P)$(M)")
|
||||||
|
{
|
||||||
|
field(DESC,"$(DESC)")
|
||||||
|
field(DTYP,"$(DTYP)")
|
||||||
|
field(DIR,"$(DIR)")
|
||||||
|
field(VELO,"$(VELO)")
|
||||||
|
field(VMAX,"$(VMAX=$(VELO))")
|
||||||
|
field(VBAS,"$(VBAS)")
|
||||||
|
field(ACCL,"$(ACCL)")
|
||||||
|
field(BDST,"$(BDST)")
|
||||||
|
field(BVEL,"$(BVEL)")
|
||||||
|
field(BACC,"$(BACC)")
|
||||||
|
field(OUT,"@asyn($(PORT),$(ADDR))")
|
||||||
|
field(MRES,"$(MRES)")
|
||||||
|
field(PREC,"$(PREC)")
|
||||||
|
field(EGU,"$(EGU)")
|
||||||
|
field(DHLM,"$(DHLM)")
|
||||||
|
field(DLLM,"$(DLLM)")
|
||||||
|
field(INIT,"$(INIT)")
|
||||||
|
field(TWV,"1")
|
||||||
|
field(RDBD,"$(RDBD)")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# The message text
|
||||||
|
record(waveform, "$(P)$(M)-MsgTxt") {
|
||||||
|
field(DTYP, "asynOctetRead")
|
||||||
|
field(INP, "@asyn($(PORT),$(N),1) MOTOR_MESSAGE_TEXT")
|
||||||
|
field(FTVL, "CHAR")
|
||||||
|
field(NELM, "80")
|
||||||
|
field(SCAN, "I/O Intr")
|
||||||
|
}
|
||||||
|
|
||||||
|
# enable axis
|
||||||
|
record(longout, "$(P)$(M):Enable") {
|
||||||
|
field(DTYP, "asynInt32")
|
||||||
|
field(OUT, "@asyn($(PORT),$(N),1) ENABLE_AXIS")
|
||||||
|
field(PINI, "YES")
|
||||||
|
}
|
||||||
|
|
||||||
|
# enable axis
|
||||||
|
record(longin, "$(P)$(M):Enable_RBV") {
|
||||||
|
field(DTYP, "asynInt32")
|
||||||
|
field(INP, "@asyn($(PORT),$(N),1) AXIS_ENABLED")
|
||||||
|
field(PINI, "YES")
|
||||||
|
field(SCAN, "1 second")
|
||||||
|
}
|
||||||
|
|
@ -181,21 +181,21 @@ asynStatus EL734Controller::transactController(int axisNo,char command[COMLEN],
|
|||||||
}
|
}
|
||||||
if(strstr(myReply,"?cmd") != NULL){
|
if(strstr(myReply,"?cmd") != NULL){
|
||||||
snprintf(errTxt,sizeof(errTxt), "Bad command %s at axis %d", command, axisNo);
|
snprintf(errTxt,sizeof(errTxt), "Bad command %s at axis %d", command, axisNo);
|
||||||
errlogSevPrintf(errlogMajor, errTxt);
|
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, errTxt);
|
||||||
if(axis!= NULL){
|
if(axis!= NULL){
|
||||||
axis->updateMsgTxtFromDriver(errTxt);
|
axis->updateMsgTxtFromDriver(errTxt);
|
||||||
}
|
}
|
||||||
return asynError;
|
return asynError;
|
||||||
} else if(strstr(myReply,"?par") != NULL){
|
} else if(strstr(myReply,"?par") != NULL){
|
||||||
snprintf(errTxt,sizeof(errTxt), "Bad parameter in command %s", command);
|
snprintf(errTxt,sizeof(errTxt), "Bad parameter in command %s", command);
|
||||||
errlogSevPrintf(errlogMajor, errTxt);
|
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, errTxt);
|
||||||
if(axis!= NULL){
|
if(axis!= NULL){
|
||||||
axis->updateMsgTxtFromDriver(errTxt);
|
axis->updateMsgTxtFromDriver(errTxt);
|
||||||
}
|
}
|
||||||
return asynError;
|
return asynError;
|
||||||
} else if(strstr(myReply,"?rng") != NULL){
|
} else if(strstr(myReply,"?rng") != NULL){
|
||||||
snprintf(errTxt,sizeof(errTxt), "Parameter out of range in command %s", command);
|
snprintf(errTxt,sizeof(errTxt), "Parameter out of range in command %s", command);
|
||||||
errlogSevPrintf(errlogMajor, errTxt);
|
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, errTxt);
|
||||||
if(axis!= NULL){
|
if(axis!= NULL){
|
||||||
axis->updateMsgTxtFromDriver(errTxt);
|
axis->updateMsgTxtFromDriver(errTxt);
|
||||||
}
|
}
|
||||||
@ -233,10 +233,12 @@ EL734Axis::EL734Axis(EL734Controller *pC, int axisNo)
|
|||||||
pC_->setDoubleParam(axisNo_,pC_->motorHighLimit_,high);
|
pC_->setDoubleParam(axisNo_,pC_->motorHighLimit_,high);
|
||||||
callParamCallbacks();
|
callParamCallbacks();
|
||||||
} else {
|
} else {
|
||||||
errlogPrintf("Bad response - %s - requesting limits at axis %d", reply, axisNo_);
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
|
"Bad response - %s - requesting limits at axis %d", reply, axisNo_);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
errlogPrintf("Failed to read limits at axis %d", axisNo_);
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
|
"Failed to read limits at axis %d", axisNo_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +284,8 @@ asynStatus EL734Axis::move(double position, int relative, double minVelocity, do
|
|||||||
oredMSR = 0;
|
oredMSR = 0;
|
||||||
homing = 0;
|
homing = 0;
|
||||||
errorReported = 0;
|
errorReported = 0;
|
||||||
errlogPrintf("Starting axis %d with destination %f", axisNo_,position/1000);
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
|
"Starting axis %d with destination %f", axisNo_,position/1000);
|
||||||
sprintf(command, "p %d %.3f", axisNo_, position/1000.);
|
sprintf(command, "p %d %.3f", axisNo_, position/1000.);
|
||||||
status = pC_->transactController(axisNo_,command,reply);
|
status = pC_->transactController(axisNo_,command,reply);
|
||||||
setIntegerParam(pC_->motorStatusProblem_, false);
|
setIntegerParam(pC_->motorStatusProblem_, false);
|
||||||
@ -347,7 +350,7 @@ asynStatus EL734Axis::stop(double acceleration )
|
|||||||
if(moving && errorReported == 0){
|
if(moving && errorReported == 0){
|
||||||
sprintf(command, "S %d", axisNo_);
|
sprintf(command, "S %d", axisNo_);
|
||||||
status = pC_->transactController(axisNo_,command,reply);
|
status = pC_->transactController(axisNo_,command,reply);
|
||||||
errlogPrintf("Sent STOP on Axis %d\n", axisNo_);
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "Sent STOP on Axis %d\n", axisNo_);
|
||||||
updateMsgTxtFromDriver("Axis interrupted");
|
updateMsgTxtFromDriver("Axis interrupted");
|
||||||
errorReported = 1;
|
errorReported = 1;
|
||||||
}
|
}
|
||||||
@ -443,7 +446,8 @@ asynStatus EL734Axis::poll(bool *moving)
|
|||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
errlogPrintf("Axis %d, reply %s, position %lf\n", axisNo_, reply, position);
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
|
"Axis %d, reply %s, position %lf\n", axisNo_, reply, position);
|
||||||
setDoubleParam(pC_->motorPosition_, position*1000);
|
setDoubleParam(pC_->motorPosition_, position*1000);
|
||||||
//setDoubleParam(pC_->motorEncoderPosition_, position);
|
//setDoubleParam(pC_->motorEncoderPosition_, position);
|
||||||
}
|
}
|
||||||
@ -492,7 +496,7 @@ asynStatus EL734Axis::poll(bool *moving)
|
|||||||
if(oredMSR & 0x1000){
|
if(oredMSR & 0x1000){
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||||
// errlogPrintf("Detected air cushion error on %d", axisNo_);
|
// errlogPrintf("Detected air cushion error on %d", axisNo_);
|
||||||
errlogSevPrintf(errlogMajor, "Air cushion problem on %d", axisNo_);
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "Air cushion problem on %d", axisNo_);
|
||||||
updateMsgTxtFromDriver("Air cushion error");
|
updateMsgTxtFromDriver("Air cushion error");
|
||||||
errorReported = 1;
|
errorReported = 1;
|
||||||
comStatus = asynError;
|
comStatus = asynError;
|
||||||
@ -500,7 +504,7 @@ asynStatus EL734Axis::poll(bool *moving)
|
|||||||
}
|
}
|
||||||
if(oredMSR & 0x100){
|
if(oredMSR & 0x100){
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||||
errlogSevPrintf(errlogMajor, "Run failure at %d", axisNo_);
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "Run failure at %d", axisNo_);
|
||||||
updateMsgTxtFromDriver("Run failure");
|
updateMsgTxtFromDriver("Run failure");
|
||||||
comStatus = asynError;
|
comStatus = asynError;
|
||||||
errorReported = 1;
|
errorReported = 1;
|
||||||
@ -508,14 +512,14 @@ asynStatus EL734Axis::poll(bool *moving)
|
|||||||
}
|
}
|
||||||
if(oredMSR & 0x400){
|
if(oredMSR & 0x400){
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||||
errlogSevPrintf(errlogMajor, "Positioning failure at %d", axisNo_);
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "Positioning failure at %d", axisNo_);
|
||||||
updateMsgTxtFromDriver("Positioning failure");
|
updateMsgTxtFromDriver("Positioning failure");
|
||||||
comStatus = asynError;
|
comStatus = asynError;
|
||||||
errorReported = 1;
|
errorReported = 1;
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
if(oredMSR & 0x200 || oredMSR & 0x80) {
|
if(oredMSR & 0x200 || oredMSR & 0x80) {
|
||||||
errlogSevPrintf(errlogMinor, "Positioning fault at %d", axisNo_);
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_WARNING, "Positioning fault at %d", axisNo_);
|
||||||
}
|
}
|
||||||
setIntegerParam(pC_->motorStatusProblem_, false);
|
setIntegerParam(pC_->motorStatusProblem_, false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -269,15 +269,18 @@ asynStatus
|
|||||||
* overwritten when we read back the status at the end, but that's OK */
|
* overwritten when we read back the status at the end, but that's OK */
|
||||||
pAxis->setIntegerParam(function, value);
|
pAxis->setIntegerParam(function, value);
|
||||||
|
|
||||||
|
if(function == motorStop_){
|
||||||
|
errlogPrintf("Stop called with value %d\n", value);
|
||||||
|
double accel;
|
||||||
|
getDoubleParam(pAxis->axisNo_, motorAccel_, &accel);
|
||||||
|
status = pAxis->stop(accel);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
if (function == enableAxis_) {
|
if (function == enableAxis_) {
|
||||||
/*
|
/*
|
||||||
* Read the status in order to prevent execssive commands
|
* Read the status in order to prevent execssive commands
|
||||||
*/
|
*/
|
||||||
devStatus = pAxis->readStatus();
|
devStatus = pAxis->readStatus();
|
||||||
if(devStatus < 900){
|
|
||||||
errlogPrintf("MMACS: Motor %d not ready to switch on\n", pAxis->axisNo_);
|
|
||||||
return asynError;
|
|
||||||
}
|
|
||||||
if (value == 1 && !pAxis->isOn(devStatus) ) {
|
if (value == 1 && !pAxis->isOn(devStatus) ) {
|
||||||
/* download parameters, does not work as of now */
|
/* download parameters, does not work as of now */
|
||||||
/*
|
/*
|
||||||
@ -309,6 +312,7 @@ asynStatus
|
|||||||
if(pAxis->isOn(devStatus) == value){
|
if(pAxis->isOn(devStatus) == value){
|
||||||
pAxis->active = true;
|
pAxis->active = true;
|
||||||
pAxis->poll(&moving); // to update the Enable_RBV field
|
pAxis->poll(&moving); // to update the Enable_RBV field
|
||||||
|
pAxis->active = false;
|
||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
}
|
}
|
||||||
usleep(200);
|
usleep(200);
|
||||||
@ -388,12 +392,11 @@ asynStatus
|
|||||||
MasterMACSAxis::move(double position, int relative, double minVelocity,
|
MasterMACSAxis::move(double position, int relative, double minVelocity,
|
||||||
double maxVelocity, double acceleration)
|
double maxVelocity, double acceleration)
|
||||||
{
|
{
|
||||||
asynStatus status;
|
asynStatus status = asynSuccess;
|
||||||
char command[COMLEN], reply[COMLEN];
|
char command[COMLEN], reply[COMLEN];
|
||||||
int devStatus;
|
int devStatus;
|
||||||
|
|
||||||
errlogPrintf("minVelocity = %f, maxVelocity = %f\n", minVelocity,
|
//errlogPrintf("minVelocity = %f, maxVelocity = %f\n", minVelocity, maxVelocity);
|
||||||
maxVelocity);
|
|
||||||
memset(command, 0, COMLEN * sizeof(char));
|
memset(command, 0, COMLEN * sizeof(char));
|
||||||
|
|
||||||
/* clear motor error message */
|
/* clear motor error message */
|
||||||
@ -409,18 +412,9 @@ asynStatus
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* test if the thing is On
|
* only start if the thing is On
|
||||||
*/
|
*/
|
||||||
devStatus = readStatus();
|
devStatus = readStatus();
|
||||||
if(devStatus < 900) {
|
|
||||||
return asynError;
|
|
||||||
}
|
|
||||||
if (!isOn(devStatus)) {
|
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
|
||||||
updateMsgTxtFromDriver("Motor disabled");
|
|
||||||
errlogPrintf("ERROR: trying to start disabled axis %d\n", axisNo_);
|
|
||||||
return asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set speed
|
* set speed
|
||||||
@ -431,30 +425,38 @@ asynStatus
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (relative) {
|
if (relative) {
|
||||||
position += this->position;
|
position += this->position;
|
||||||
}
|
|
||||||
errlogPrintf("Starting axis %d with destination %f", axisNo_,
|
|
||||||
position / 1000.);
|
|
||||||
|
|
||||||
/* send target position */
|
|
||||||
sprintf(command, "%dS02= %.3f", axisNo_, position / 1000.);
|
|
||||||
status = pC_->transactController(axisNo_, command, reply);
|
|
||||||
if (status == asynError) {
|
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send move command */
|
if(isOn(devStatus) && active == false) {
|
||||||
sprintf(command, "%dS00=1", axisNo_);
|
errlogPrintf("Starting axis %d with destination %f\n", axisNo_,
|
||||||
status = pC_->transactController(axisNo_, command, reply);
|
position / 1000.);
|
||||||
if (status == asynError) {
|
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
hasStarted = true;
|
|
||||||
homing = 0;
|
|
||||||
active = true;
|
|
||||||
|
|
||||||
|
/* send target position */
|
||||||
|
sprintf(command, "%dS02= %.3f", axisNo_, position / 1000.);
|
||||||
|
status = pC_->transactController(axisNo_, command, reply);
|
||||||
|
if (status == asynError) {
|
||||||
|
errlogPrintf("MMACS: failed to set target on %d\n", axisNo_);
|
||||||
|
updateMsgTxtFromDriver("Failed to send target position");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send move command */
|
||||||
|
sprintf(command, "%dS00=1", axisNo_);
|
||||||
|
status = pC_->transactController(axisNo_, command, reply);
|
||||||
|
if (status == asynError) {
|
||||||
|
errlogPrintf("MMACS: failed to start axis %d\n", axisNo_);
|
||||||
|
updateMsgTxtFromDriver("Failed to start axis");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
hasStarted = true;
|
||||||
|
homing = 0;
|
||||||
|
active = true;
|
||||||
|
usleep(500);
|
||||||
|
lastPositionUpdate = time(NULL);
|
||||||
|
} else {
|
||||||
|
errlogPrintf("MMACS: axis %d disabled, cannot start\n", axisNo_);
|
||||||
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,26 +474,20 @@ asynStatus
|
|||||||
* test if the thing is On
|
* test if the thing is On
|
||||||
*/
|
*/
|
||||||
devStatus = readStatus();
|
devStatus = readStatus();
|
||||||
if(devStatus < 900) {
|
|
||||||
return asynError;
|
|
||||||
}
|
|
||||||
if (!isOn(devStatus)) {
|
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
|
||||||
updateMsgTxtFromDriver("Motor disabled");
|
|
||||||
errlogPrintf("ERROR: trying to home disabled axis %d\n", axisNo_);
|
|
||||||
return asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
setIntegerParam(pC_->motorStatusProblem_, false);
|
|
||||||
updateMsgTxtFromDriver("");
|
updateMsgTxtFromDriver("");
|
||||||
|
|
||||||
|
if(isOn(devStatus)){
|
||||||
sprintf(command, "%dS00=9", axisNo_);
|
sprintf(command, "%dS00=9", axisNo_);
|
||||||
homing = 1;
|
homing = 1;
|
||||||
status = pC_->transactController(axisNo_, command, reply);
|
status = pC_->transactController(axisNo_, command, reply);
|
||||||
hasStarted = true;
|
hasStarted = true;
|
||||||
active = true;
|
active = true;
|
||||||
return status;
|
lastPositionUpdate = time(NULL);
|
||||||
|
return status;
|
||||||
|
} else {
|
||||||
|
errlogPrintf("MMACS: cannot home disabled axis %d\n", axisNo_);
|
||||||
|
return asynError;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus
|
asynStatus
|
||||||
@ -552,9 +548,8 @@ asynStatus MasterMACSAxis::poll(bool * moving)
|
|||||||
{
|
{
|
||||||
asynStatus comStatus = asynSuccess;
|
asynStatus comStatus = asynSuccess;
|
||||||
char command[COMLEN], reply[COMLEN], *pPtr, buffer[80];
|
char command[COMLEN], reply[COMLEN], *pPtr, buffer[80];
|
||||||
float errStatus;
|
|
||||||
unsigned int errCode, derCode, devStatus;
|
unsigned int errCode, derCode, devStatus;
|
||||||
|
float errStatus;
|
||||||
struct tm* tm_info;
|
struct tm* tm_info;
|
||||||
time_t timer;
|
time_t timer;
|
||||||
|
|
||||||
@ -574,6 +569,7 @@ asynStatus MasterMACSAxis::poll(bool * moving)
|
|||||||
strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
|
strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
|
||||||
errlogPrintf("poll called at %s on axis %d \n",
|
errlogPrintf("poll called at %s on axis %d \n",
|
||||||
buffer, axisNo_ );
|
buffer, axisNo_ );
|
||||||
|
lastPoll = time(NULL);
|
||||||
|
|
||||||
setIntegerParam(pC_->motorStatusProblem_, false);
|
setIntegerParam(pC_->motorStatusProblem_, false);
|
||||||
memset(command, 0, COMLEN * sizeof(char));
|
memset(command, 0, COMLEN * sizeof(char));
|
||||||
@ -581,48 +577,51 @@ asynStatus MasterMACSAxis::poll(bool * moving)
|
|||||||
// Read the current motor position
|
// Read the current motor position
|
||||||
sprintf(command, "%dR12", axisNo_);
|
sprintf(command, "%dR12", axisNo_);
|
||||||
comStatus = pC_->transactController(axisNo_, command, reply);
|
comStatus = pC_->transactController(axisNo_, command, reply);
|
||||||
if (comStatus == asynError) {
|
if(comStatus != asynError) {
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
pPtr = strstr(reply, "=");
|
||||||
goto skip;
|
if(pPtr) {
|
||||||
}
|
sscanf(pPtr + 1, "%lf", &position);
|
||||||
pPtr = strstr(reply, "=");
|
setDoubleParam(pC_->motorPosition_, position * 1000.);
|
||||||
if (pPtr) {
|
setDoubleParam(pC_->motorEncoderPosition_, position * 1000.);
|
||||||
sscanf(pPtr + 1, "%lf", &position);
|
/*
|
||||||
|
* keep track of position in order to check for a stuck motor later
|
||||||
|
*/
|
||||||
|
if(ABS(position - oldPosition) > 1){
|
||||||
|
oldPosition = position;
|
||||||
|
lastPositionUpdate = time(NULL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errlogPrintf("MMACS: Invalid response asking position on %d\n", axisNo_);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
errlogPrintf("Received malformed reply: Axis %d, reply %s\n",
|
errlogPrintf("MMACS: communication problem reading axis %d position\n", axisNo_);
|
||||||
axisNo_, reply + 4);
|
|
||||||
comStatus = asynError;
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
|
|
||||||
setDoubleParam(pC_->motorPosition_, position * 1000.);
|
|
||||||
setDoubleParam(pC_->motorEncoderPosition_, position * 1000.);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* keep track of position in order to check for a stuck motor later
|
|
||||||
*/
|
|
||||||
if(ABS(position - oldPosition) > 1){
|
|
||||||
oldPosition = position;
|
|
||||||
lastPositionUpdate = time(NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the overall status of this motor */
|
// Read the overall status of this motor */
|
||||||
devStatus = readStatus();
|
devStatus = readStatus();
|
||||||
if(devStatus < 900) {
|
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
errlogPrintf("Axis %d, position %lf, devStatus %d\n", axisNo_,
|
errlogPrintf("Axis %d, position %lf, devStatus %d\n", axisNo_,
|
||||||
position, devStatus);
|
position, devStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for the thing being in a bad state
|
||||||
|
if(CHECK_BIT(devStatus, 6)) {
|
||||||
|
*moving = false;
|
||||||
|
active = false;
|
||||||
|
setIntegerParam(pC_->motorStatusDone_, true);
|
||||||
|
updateMsgTxtFromDriver("AXIS dead");
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setIntegerParam(pC_->enableAxis_, isOn(devStatus));
|
||||||
setIntegerParam(pC_->axisEnabled_, isOn(devStatus));
|
setIntegerParam(pC_->axisEnabled_, isOn(devStatus));
|
||||||
|
|
||||||
|
// Check if the motor is disabled
|
||||||
if (!isOn(devStatus)) {
|
if (!isOn(devStatus)) {
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
updateMsgTxtFromDriver("Axis disabled");
|
||||||
updateMsgTxtFromDriver("Motor disabled");
|
|
||||||
*moving = false;
|
*moving = false;
|
||||||
|
active = false;
|
||||||
setIntegerParam(pC_->motorStatusDone_, true);
|
setIntegerParam(pC_->motorStatusDone_, true);
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
@ -631,9 +630,10 @@ asynStatus MasterMACSAxis::poll(bool * moving)
|
|||||||
* if the motor has never run, the status bit 10 is invalid
|
* if the motor has never run, the status bit 10 is invalid
|
||||||
*/
|
*/
|
||||||
if (!hasStarted) {
|
if (!hasStarted) {
|
||||||
*moving = false;
|
*moving = false;
|
||||||
setIntegerParam(pC_->motorStatusDone_, true);
|
setIntegerParam(pC_->motorStatusDone_, true);
|
||||||
goto skip;
|
active = false;
|
||||||
|
goto skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -643,11 +643,13 @@ asynStatus MasterMACSAxis::poll(bool * moving)
|
|||||||
/* we are still creeping along .... */
|
/* we are still creeping along .... */
|
||||||
*moving = true;
|
*moving = true;
|
||||||
setIntegerParam(pC_->motorStatusDone_, false);
|
setIntegerParam(pC_->motorStatusDone_, false);
|
||||||
if(time(NULL) > lastPositionUpdate + 60) {
|
if(time(NULL) > lastPositionUpdate + 120) {
|
||||||
// we are detecting a stuck motor
|
// we are detecting a stuck motor
|
||||||
errlogPrintf("MMACS: axis %d is STUCK!!\n", axisNo_);
|
errlogPrintf("MMACS: axis %d is STUCK!!\n", axisNo_);
|
||||||
updateMsgTxtFromDriver("Axis STUCK!!");
|
updateMsgTxtFromDriver("Axis STUCK!!");
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
setIntegerParam(pC_->motorStatusDone_, true);
|
||||||
|
*moving = false;
|
||||||
|
active = false;
|
||||||
}
|
}
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
@ -657,29 +659,25 @@ asynStatus MasterMACSAxis::poll(bool * moving)
|
|||||||
*moving = false;
|
*moving = false;
|
||||||
active = false;
|
active = false;
|
||||||
setIntegerParam(pC_->motorStatusDone_, true);
|
setIntegerParam(pC_->motorStatusDone_, true);
|
||||||
|
updateMsgTxtFromDriver("");
|
||||||
|
|
||||||
/* when homing, set the proper flag */
|
/* when homing, set the proper flag */
|
||||||
if (homing) {
|
if (homing) {
|
||||||
setIntegerParam(pC_->motorStatusAtHome_, true);
|
setIntegerParam(pC_->motorStatusAtHome_, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for limit switches*/
|
/* check for limit switches*/
|
||||||
setIntegerParam(pC_->motorStatusLowLimit_, false);
|
setIntegerParam(pC_->motorStatusLowLimit_, false);
|
||||||
setIntegerParam(pC_->motorStatusHighLimit_, false);
|
setIntegerParam(pC_->motorStatusHighLimit_, false);
|
||||||
if (CHECK_BIT(devStatus, 11)) {
|
if (CHECK_BIT(devStatus, 11)) {
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
errlogSevPrintf(errlogMajor, "Limit bit in status code %d", axisNo_);
|
||||||
errlogSevPrintf(errlogMajor,
|
|
||||||
"Limit bit in status code %d",
|
|
||||||
axisNo_);
|
|
||||||
/* guessing which limit has been hit ... */
|
/* guessing which limit has been hit ... */
|
||||||
if (position > 0) {
|
if (position > 0) {
|
||||||
updateMsgTxtFromDriver("Hit positive limit switch");
|
updateMsgTxtFromDriver("Hit positive limit switch");
|
||||||
setIntegerParam(pC_->motorStatusHighLimit_, true);
|
setIntegerParam(pC_->motorStatusHighLimit_, true);
|
||||||
setIntegerParam(pC_->motorStatusProblem_, false);
|
|
||||||
} else {
|
} else {
|
||||||
updateMsgTxtFromDriver("Hit negative limit switch");
|
updateMsgTxtFromDriver("Hit negative limit switch");
|
||||||
setIntegerParam(pC_->motorStatusLowLimit_, true);
|
setIntegerParam(pC_->motorStatusLowLimit_, true);
|
||||||
setIntegerParam(pC_->motorStatusProblem_, false);
|
|
||||||
}
|
}
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
@ -689,44 +687,45 @@ asynStatus MasterMACSAxis::poll(bool * moving)
|
|||||||
/* read error codes */
|
/* read error codes */
|
||||||
sprintf(command, "%dR11", axisNo_);
|
sprintf(command, "%dR11", axisNo_);
|
||||||
comStatus = pC_->transactController(axisNo_, command, reply);
|
comStatus = pC_->transactController(axisNo_, command, reply);
|
||||||
if (comStatus == asynError) {
|
if (comStatus != asynError) {
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
pPtr = strstr(reply, "=");
|
||||||
goto skip;
|
if(pPtr) {
|
||||||
}
|
sscanf(pPtr + 1, "%f", &errStatus);
|
||||||
pPtr = strstr(reply, "=");
|
errCode = (unsigned int) errStatus;
|
||||||
if(pPtr) {
|
|
||||||
sscanf(pPtr + 1, "%f", &errStatus);
|
} else {
|
||||||
errCode = (unsigned int) errStatus;
|
errlogPrintf("MMACS: axis %d received invalid reply asking for error code \n", axisNo_);
|
||||||
|
errCode = 0;
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
errlogPrintf("MMACS: axis %d received invalid reply asking for error code \n", axisNo_);
|
errlogPrintf("MMACS: axis %d failed reading error code \n", axisNo_);
|
||||||
updateMsgTxtFromDriver("Invalid reply asking error code R11");
|
|
||||||
errCode = 0;
|
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(command, "%dR18", axisNo_);
|
sprintf(command, "%dR18", axisNo_);
|
||||||
comStatus = pC_->transactController(axisNo_, command, reply);
|
comStatus = pC_->transactController(axisNo_, command, reply);
|
||||||
if (comStatus == asynError) {
|
if (comStatus != asynError) {
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
pPtr = strstr(reply, "=");
|
||||||
goto skip;
|
if(pPtr) {
|
||||||
}
|
sscanf(pPtr + 1, "%f", &errStatus);
|
||||||
pPtr = strstr(reply, "=");
|
derCode = (unsigned int) errStatus;
|
||||||
if(pPtr) {
|
} else {
|
||||||
sscanf(pPtr + 1, "%f", &errStatus);
|
errlogPrintf("MMACS: malformed reply for R18: %s, on axis %d\n", reply, axisNo_);
|
||||||
derCode = (unsigned int) errStatus;
|
derCode = 0;
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
errlogPrintf("MMACS: malformed reply for R18: %s, on axis %d\n", reply, axisNo_);
|
errlogPrintf("MMACS: axis %d failed reading extended error code R18 \n", axisNo_);
|
||||||
derCode = 0;
|
goto skip;
|
||||||
updateMsgTxtFromDriver("Invalid reply asking error code R18");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
errlogPrintf("Axis %d, errCode(R11) %d, derCode(R18) %d\n", axisNo_,
|
errlogPrintf("Axis %d, errCode(R11) %d, derCode(R18) %d\n", axisNo_,
|
||||||
errCode, derCode);
|
errCode, derCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
|
||||||
if (errCode == 0) {
|
if (errCode == 0) {
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
|
||||||
errlogSevPrintf(errlogMajor,
|
errlogSevPrintf(errlogMajor,
|
||||||
"Fault bit in status code, but no error code on %d\n", axisNo_);
|
"Fault bit in status code, but no error code on %d\n", axisNo_);
|
||||||
updateMsgTxtFromDriver ("Fault bit in status code without error code");
|
updateMsgTxtFromDriver ("Fault bit in status code without error code");
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
drvAsynMMACSPort.c. The driver will not work with a standard asyn IPPort,
|
drvAsynMMACSPort.c. The driver will not work with a standard asyn IPPort,
|
||||||
only with the special one.
|
only with the special one.
|
||||||
|
|
||||||
Mark Koennecke, March 2023
|
Mark Koennecke, March, August, 2023
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SINQController.h"
|
#include "SINQController.h"
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <asynOctetSyncIO.h>
|
#include <asynOctetSyncIO.h>
|
||||||
#include <epicsEvent.h>
|
#include <epicsEvent.h>
|
||||||
#include <epicsThread.h>
|
#include <epicsThread.h>
|
||||||
@ -484,9 +485,7 @@ static void runEvents(EL737priv *priv)
|
|||||||
// errlogPrintf("EL737: Starting preset timer\n");
|
// errlogPrintf("EL737: Starting preset timer\n");
|
||||||
}
|
}
|
||||||
status = el737_transactCommand(priv,command,reply);
|
status = el737_transactCommand(priv,command,reply);
|
||||||
if(status == asynSuccess){
|
priv->counting = 1;
|
||||||
priv->counting = 1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if(priv->counting) {
|
if(priv->counting) {
|
||||||
/* Stop */
|
/* Stop */
|
||||||
@ -568,7 +567,8 @@ static void el737Thread(void *param)
|
|||||||
*/
|
*/
|
||||||
runEvents(priv);
|
runEvents(priv);
|
||||||
if(priv->counting == 1){
|
if(priv->counting == 1){
|
||||||
timeout = .2;
|
timeout = .2;
|
||||||
|
usleep(500);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
@ -287,7 +287,7 @@ asynStatus pmacAxis::setPosition(double position) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
asynStatus pmacAxis::stop(double acceleration) {
|
asynStatus pmacAxis::stop(double acceleration) {
|
||||||
asynStatus status = asynError;
|
asynStatus status = asynSuccess;
|
||||||
static const char *functionName = "pmacAxis::stopAxis";
|
static const char *functionName = "pmacAxis::stopAxis";
|
||||||
bool moving = false;
|
bool moving = false;
|
||||||
|
|
||||||
@ -489,7 +489,6 @@ asynStatus pmacAxis::getAxisStatus(bool *moving) {
|
|||||||
*moving = false;
|
*moving = false;
|
||||||
setIntegerParam(pC_->motorStatusMoving_, false);
|
setIntegerParam(pC_->motorStatusMoving_, false);
|
||||||
setIntegerParam(pC_->motorStatusDone_, true);
|
setIntegerParam(pC_->motorStatusDone_, true);
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
|
||||||
errlogPrintf("Axis %d did not start within 10 seconds!! BROKEN\n", axisNo_);
|
errlogPrintf("Axis %d did not start within 10 seconds!! BROKEN\n", axisNo_);
|
||||||
updateMsgTxtFromDriver("Axis did not start within 10 seconds");
|
updateMsgTxtFromDriver("Axis did not start within 10 seconds");
|
||||||
starting = 0;
|
starting = 0;
|
||||||
@ -614,7 +613,6 @@ asynStatus pmacHRPTAxis::getAxisStatus(bool *moving) {
|
|||||||
*moving = false;
|
*moving = false;
|
||||||
setIntegerParam(pC_->motorStatusMoving_, false);
|
setIntegerParam(pC_->motorStatusMoving_, false);
|
||||||
setIntegerParam(pC_->motorStatusDone_, true);
|
setIntegerParam(pC_->motorStatusDone_, true);
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -955,7 +953,8 @@ asynStatus pmacV3Axis::getAxisStatus(bool *moving) {
|
|||||||
pmacV3Controller *p3C_ = (pmacV3Controller *)pC_;
|
pmacV3Controller *p3C_ = (pmacV3Controller *)pC_;
|
||||||
IsEnable = axStat != -3;
|
IsEnable = axStat != -3;
|
||||||
|
|
||||||
asynStatus st = setIntegerParam(p3C_->axisEnabled_, IsEnable);
|
setIntegerParam(p3C_->axisEnabled_, IsEnable);
|
||||||
|
asynStatus st = setIntegerParam(p3C_->enableAxis_, IsEnable);
|
||||||
cmdStatus = cmdStatus > st ? cmdStatus : st;
|
cmdStatus = cmdStatus > st ? cmdStatus : st;
|
||||||
|
|
||||||
int direction = 0;
|
int direction = 0;
|
||||||
@ -993,7 +992,7 @@ asynStatus pmacV3Axis::getAxisStatus(bool *moving) {
|
|||||||
// /*
|
// /*
|
||||||
// code to test against too long status 5 or 6
|
// code to test against too long status 5 or 6
|
||||||
// */
|
// */
|
||||||
int EstimatedTimeOfArrival = 60;
|
int EstimatedTimeOfArrival = 120;
|
||||||
if (axStat == 5 || axStat == 6) {
|
if (axStat == 5 || axStat == 6) {
|
||||||
if (status6Time == 0) {
|
if (status6Time == 0) {
|
||||||
status6Time = time(NULL);
|
status6Time = time(NULL);
|
||||||
@ -1472,7 +1471,6 @@ asynStatus AmorDetectorAxis::poll(bool *moving)
|
|||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
"AmorDetectorAxis::poll: %s", errorMessage);
|
"AmorDetectorAxis::poll: %s", errorMessage);
|
||||||
updateMsgTxtFromDriver(errorMessage);
|
updateMsgTxtFromDriver(errorMessage);
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
|
||||||
status = asynError;
|
status = asynError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
testel737.cmd
Executable file
11
testel737.cmd
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/local/bin/iocsh
|
||||||
|
|
||||||
|
require sinq,koennecke
|
||||||
|
|
||||||
|
epicsEnvSet("TOP","/afs/psi.ch/project/sinqdev/sinqepicsapp")
|
||||||
|
|
||||||
|
#--------- load EL737 counter box
|
||||||
|
drvAsynIPPortConfigure("cter1","localhost:62000",0,0,0)
|
||||||
|
dbLoadRecords("$(TOP)/db/asynRecord.db","P=KM36:,R=cter1,PORT=cter1,ADDR=0,OMAX=80,IMAX=80")
|
||||||
|
dbLoadRecords("${TOP}/db/el737Record.db","P=KM36:counter,PORT=cter1,DESC=SANSCounter")
|
||||||
|
|
@ -59,7 +59,7 @@ def scan_substitution_file(filename):
|
|||||||
# import pdb; pdb.set_trace()
|
# import pdb; pdb.set_trace()
|
||||||
with open(filename, 'r') as fin:
|
with open(filename, 'r') as fin:
|
||||||
rawline = fin.readline()
|
rawline = fin.readline()
|
||||||
import pdb; pdb.set_trace()
|
# import pdb; pdb.set_trace()
|
||||||
while rawline:
|
while rawline:
|
||||||
line = rawline.replace(' ','')
|
line = rawline.replace(' ','')
|
||||||
line = line.strip('{}')
|
line = line.strip('{}')
|
||||||
|
Reference in New Issue
Block a user