Many improvements to the MasterMACS motor driver. It is working but the hardware is shaky.
Added support for dose rate controlled Phytron motors. Not tested! Small bug fixes
This commit is contained in:
@@ -77,12 +77,27 @@ PhytronController::PhytronController(const char *portName, const char *PhytronPo
|
||||
pasynOctetSyncIO->setOutputEos(pasynUserController_,etx,strlen(etx));
|
||||
pasynOctetSyncIO->setInputEos(pasynUserController_,etx,strlen(etx));
|
||||
|
||||
new PhytronAxis(this, 1, encX);
|
||||
new PhytronAxis(this, 2, encY);
|
||||
/* The special selector D selects the dose controlled axis version */
|
||||
if(strcmp(sel, (const char *)"D") == 0) {
|
||||
new PhytronDoseAxis(this, 1, encX);
|
||||
new PhytronDoseAxis(this, 2, encY);
|
||||
} else {
|
||||
new PhytronAxis(this, 1, encX);
|
||||
new PhytronAxis(this, 2, encY);
|
||||
}
|
||||
|
||||
|
||||
startPoller(1000./1000., IDLEPOLL, 2);
|
||||
}
|
||||
|
||||
PhytronDoseController::PhytronDoseController(const char *portName, const char *PhytronPortName, const char *sel ,
|
||||
int encX, int encY)
|
||||
: PhytronController(portName, PhytronPortName, sel, encX, encY)
|
||||
{
|
||||
new PhytronDoseAxis(this, 1, encX);
|
||||
new PhytronDoseAxis(this, 2, encY);
|
||||
}
|
||||
|
||||
|
||||
/** Creates a new PhytronController object.
|
||||
* Configuration command, called directly or from iocsh
|
||||
@@ -97,6 +112,14 @@ extern "C" int PhytronCreateController(const char *portName, const char *Phytron
|
||||
return(asynSuccess);
|
||||
}
|
||||
|
||||
extern "C" int PhytronDoseCreateController(const char *portName, const char *PhytronPortName, const char *selector,
|
||||
int encX, int encY)
|
||||
{
|
||||
new PhytronDoseController(portName, PhytronPortName,selector, encX, encY);
|
||||
return(asynSuccess);
|
||||
}
|
||||
|
||||
|
||||
/** Reports on status of the driver
|
||||
* \param[in] fp The file pointer on which report information will be written
|
||||
* \param[in] level The level of report detail desired
|
||||
@@ -129,6 +152,23 @@ PhytronAxis* PhytronController::getAxis(int axisNo)
|
||||
return static_cast<PhytronAxis*>(asynMotorController::getAxis(axisNo));
|
||||
}
|
||||
|
||||
/** Returns a pointer to an PhytronDoseAxis object.
|
||||
* Returns NULL if the axis number encoded in pasynUser is invalid.
|
||||
* \param[in] pasynUser asynUser structure that encodes the axis index number. */
|
||||
PhytronDoseAxis* PhytronDoseController::getAxis(asynUser *pasynUser)
|
||||
{
|
||||
return static_cast<PhytronDoseAxis*>(asynMotorController::getAxis(pasynUser));
|
||||
}
|
||||
|
||||
/** Returns a pointer to an PhytronDoseAxis object.
|
||||
* Returns NULL if the axis number encoded in pasynUser is invalid.
|
||||
* \param[in] axisNo Axis index number. */
|
||||
PhytronDoseAxis* PhytronDoseController::getAxis(int axisNo)
|
||||
{
|
||||
return static_cast<PhytronDoseAxis*>(asynMotorController::getAxis(axisNo));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* send a command to the Phytron and read the reply. Do some error and controller
|
||||
* issue fixing on the way
|
||||
@@ -569,6 +609,79 @@ asynStatus PhytronAxis::poll(bool *moving)
|
||||
return comStatus;
|
||||
}
|
||||
|
||||
/* The special PhytronDoseAxis code used when the speed is controlled through the neutron flux
|
||||
*/
|
||||
|
||||
PhytronDoseAxis::PhytronDoseAxis(PhytronController *pC, int axisNo, int enc)
|
||||
: PhytronAxis(pC, axisNo, enc)
|
||||
{
|
||||
if(axisNo == 1){
|
||||
doseChar = '3';
|
||||
} else {
|
||||
doseChar = '4';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
asynStatus PhytronDoseAxis::move(double position, int relative, double minVelocity, double maxVelocity, double acceleration)
|
||||
{
|
||||
asynStatus status;
|
||||
//static const char *functionName = "PhytronDoseAxis::move";
|
||||
char command[COMLEN], reply[COMLEN];
|
||||
float realTarget;
|
||||
|
||||
updateMsgTxtFromDriver("");
|
||||
|
||||
/*
|
||||
set conversion factor from neutron rate to speed
|
||||
*/
|
||||
sprintf(command, "R%c3S%f", doseChar, maxVelocity);
|
||||
status = pC_->transactController(axisNo_,command,reply);
|
||||
if(strstr(reply,"NACK") != NULL){
|
||||
errlogSevPrintf(errlogMajor, "Speed not accepted on %d", axisNo_);
|
||||
updateMsgTxtFromDriver("Invalid speed");
|
||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||
return asynError;
|
||||
}
|
||||
|
||||
/*
|
||||
actually send a move command
|
||||
*/
|
||||
if (relative) {
|
||||
position += this->position;
|
||||
}
|
||||
homing = 0;
|
||||
|
||||
/* set target */
|
||||
realTarget = position/1000.;
|
||||
if(realTarget > this->position) {
|
||||
sprintf(command, "R%c1S%f", doseChar,realTarget);
|
||||
} else {
|
||||
sprintf(command, "R%c2S%f", doseChar,realTarget);
|
||||
}
|
||||
status = pC_->transactController(axisNo_,command,reply);
|
||||
if(strstr(reply,"NACK") != NULL){
|
||||
errlogSevPrintf(errlogMajor, "Drive command not acknowledged on %d", axisNo_);
|
||||
updateMsgTxtFromDriver("Drive command not acknowledged");
|
||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||
return asynError;
|
||||
}
|
||||
|
||||
/* really start the move */
|
||||
sprintf(command, "R%c01S", doseChar);
|
||||
status = pC_->transactController(axisNo_,command,reply);
|
||||
if(strstr(reply,"NACK") != NULL){
|
||||
errlogSevPrintf(errlogMajor, "Drive start command not acknowledged on %d", axisNo_);
|
||||
updateMsgTxtFromDriver("Drive command not acknowledged");
|
||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||
return asynError;
|
||||
}
|
||||
|
||||
next_poll = -1;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
extern "C" asynStatus PhytronConfBrake(const char *port, /* specify which controller by port name */
|
||||
int axis, /* axis: 0, 1 */
|
||||
int brakeNO) /* brakeIO No, 1-8 */
|
||||
@@ -615,6 +728,21 @@ static void PhytronCreateContollerCallFunc(const iocshArgBuf *args)
|
||||
PhytronCreateController(args[0].sval, args[1].sval, args[2].sval, args[3].ival,args[4].ival);
|
||||
}
|
||||
|
||||
static const iocshArg PhytronDoseCreateControllerArg0 = {"Port name", iocshArgString};
|
||||
static const iocshArg PhytronDoseCreateControllerArg1 = {"Phytron port name", iocshArgString};
|
||||
static const iocshArg PhytronDoseCreateControllerArg2 = {"Phytron Selector", iocshArgString};
|
||||
static const iocshArg PhytronDoseCreateControllerArg3 = {"EncoderX", iocshArgInt};
|
||||
static const iocshArg PhytronDoseCreateControllerArg4 = {"EncoderY", iocshArgInt};
|
||||
static const iocshArg * const PhytronDoseCreateControllerArgs[] = {&PhytronDoseCreateControllerArg0,
|
||||
&PhytronDoseCreateControllerArg1,
|
||||
&PhytronDoseCreateControllerArg2,
|
||||
&PhytronDoseCreateControllerArg3,
|
||||
&PhytronDoseCreateControllerArg4};
|
||||
static const iocshFuncDef PhytronDoseCreateControllerDef = {"PhytronDoseCreateController", 5, PhytronDoseCreateControllerArgs};
|
||||
static void PhytronDoseCreateContollerCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
PhytronDoseCreateController(args[0].sval, args[1].sval, args[2].sval, args[3].ival,args[4].ival);
|
||||
}
|
||||
|
||||
/* PhytronConfigureBrake */
|
||||
static const iocshArg phytronBrakeArg0 = {"Controller port name", iocshArgString};
|
||||
@@ -634,6 +762,7 @@ static void phytronBrakeCallFunc(const iocshArgBuf *args)
|
||||
static void PhytronRegister(void)
|
||||
{
|
||||
iocshRegister(&PhytronCreateControllerDef, PhytronCreateContollerCallFunc);
|
||||
iocshRegister(&PhytronDoseCreateControllerDef, PhytronDoseCreateContollerCallFunc);
|
||||
iocshRegister(&phytronBrakeDef, phytronBrakeCallFunc);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user