/* * GluexXPSController.cpp * * Created on: Apr 5, 2016 * Author: Hovanes Egiyan * * Modified on: Apr 10, 2016 * Vanik Kakoyan */ #include "GluexXPSController.hh" #include "GluexXPSAxis.hh" #include "GluexXPSGroup.hh" using namespace std; using namespace boost::assign; // bring 'map_list_of()' into scope static const char *driverName = "GluexXPSController"; // This overwrites the values in XPSController.cpp, so we defined it to be twice as big. #define MAX_MESSAGE_LEN 1024 #define MAX_GROUPNAME_LEN 128 // Initialize the map of controller ports std::map GluexXPSController::gxcDriverMap; GluexXPSController::GluexXPSController( const char *pName, const char *IPAddress, int IPPort, int numAxes, double movingPollPeriod, double idlePollPeriod, int enableSetPosition, double setPositionSettlingTime ) : XPSController( pName, IPAddress, IPPort, numAxes, movingPollPeriod, idlePollPeriod, enableSetPosition, setPositionSettlingTime ), gxcGroupMap() { // If a GluexXPSController driver with pName already exists throw an exception" if( gxcDriverMap.count( pName ) >0 ) { string errMessage = string( "Major Error in GluexXPSController : XPS controller asyn port " ) + string(pName) + string( " already exists" ) ; throw runtime_error( errMessage ); } // Zero all axis pointers so that we hav a way of knowing which axis was declared. for( int iAxis = 0; iAxis < numAxes; iAxis++ ) pAxes_[iAxis] = 0; // Create PCO parameters createParam( pcoSetString, asynParamInt32, &pcoSet_ ); createParam( pcoEnableString, asynParamInt32, &pcoEnable_ ); createParam( pcoDisableString, asynParamInt32, &pcoDisable_ ); createParam( pcoMinPositionString, asynParamFloat64, &pcoMinPosition_ ); createParam( pcoMaxPositionString, asynParamFloat64, &pcoMaxPosition_ ); createParam( pcoPositionStepString, asynParamFloat64, &pcoPositionStep_ ); createParam( pcoPulseWidthString, asynParamInt32, &pcoPulseWidth_ ); createParam( encoderSettlingTimeString, asynParamInt32, &encoderSettlingTime_ ); createParam( pcoMinPositionActualString, asynParamFloat64, &pcoMinPositionActual_ ); createParam( pcoMaxPositionActualString, asynParamFloat64, &pcoMaxPositionActual_ ); createParam( pcoPositionStepActualString, asynParamFloat64, &pcoPositionStepActual_ ); createParam( pcoPulseWidthActualString, asynParamFloat64, &pcoPulseWidthActual_ ); createParam( encoderSettlingTimeActualString, asynParamFloat64, &encoderSettlingTimeActual_ ); createParam( pcoPositionerNameString, asynParamOctet, &pcoPositionerName_ ); createParam( pcoEnableDisableStateString, asynParamInt32, &pcoEnableDisableState_ ); createParam( pcoMessageString, asynParamOctet, &pcoMessage_ ); createParam( pcoSetStatusString, asynParamInt32, &pcoSetStatus_ ); createParam( pcoSetMessageString, asynParamOctet, &pcoSetMessage_ ); createParam( pcoGetMessageString, asynParamOctet, &pcoGetMessage_ ); createParam( pcoEnableStatusString, asynParamInt32, &pcoEnableStatus_ ); createParam( pcoEnableMessageString, asynParamOctet, &pcoEnableMessage_ ); createParam( pcoDisableStatusString, asynParamInt32, &pcoDisableStatus_ ); createParam( pcoDisableMessageString, asynParamOctet, &pcoDisableMessage_ ); /* GroupReferencing parameters */ createParam( positionerReferencingActionExecuteString, asynParamInt32, &positionerReferencingActionExecute_); createParam( positionerReferencingActionExecuteStatusString, asynParamInt32, &positionerReferencingActionExecuteStatus_); createParam( positionerReferencingMessageString, asynParamOctet, &positionerReferencingMessage_); createParam( positionerReferencingParameterString, asynParamFloat64, &positionerReferencingParameter_); createParam( positionerReferencingSensorString, asynParamInt32, &positionerReferencingSensor_); createParam( positionerReferencingActionString, asynParamInt32, &positionerReferencingAction_); /* HomeSearchMaximumVelocity and HomePreset parameters */ createParam( positionerHomeSearchMaxVelString, asynParamFloat64, &positionerHomeSearchMaxVel_); createParam( positionerHomePresetString, asynParamFloat64, &positionerHomePreset_); /* PositionerError and PositionerStatus parameters */ createParam( positionerErrorString, asynParamInt32, &positionerError_); createParam( positionerHardwareStatusString, asynParamInt32, &positionerHardwareStatus_); createParam( positionerHardwareStatusStringString, asynParamOctet, &positionerHardwareStatusString_); createParam( positionerErrorStringString, asynParamOctet, &positionerErrorString_); // Add the pointer of this object to the static map of the port names before returning. gxcDriverMap[portName] = this; return; } GluexXPSController::~GluexXPSController() { } // This method adds an axis to the controller and figures out which group // axis to the existing or newly created group. // this axis should belong to by looking at the positionerName parameter // which has to have a form of GroupName.AxisName. After that it adds the GluexXPSAxis* GluexXPSController::addAxis( const int axis, const std::string positionerName, const double stepSize ) { const char *functionName = "addAxis"; // Make sure that the step size is not too small to cause division by zero if ( stepSize < 1.0e-25 ) { asynPrint( this->pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: bad step size\n", driverName, functionName ); return 0; } // // Make sure that there is one and only one '.' character in the positioner name. // if( ( positionerName.find(".") == string::npos ) || ( positionerName.find(".") != positionerName.rfind(".") ) ) { // asynPrint( this->pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: bad positionerName\n", driverName, functionName ); // return 0; // } // // find position of "." substring // std::size_t groupNameEndPosition = positionerName.find("."); // // pick the groupname from the subtrstring from zero to the position of "." // string groupName = positionerName.substr( 0, groupNameEndPosition ); this->lock(); // // If the controller does not already have a group with such a name add a new group // // to the map of the existing groups for this controller. // if( gxcGroupMap.count(groupName) == 0 ) { // string groupPortName = string(portName) + string("::") + groupName; // gxcGroupMap[groupName] = new GluexXPSGroup( groupPortName, this, groupName ); // } // printf( " %s groupName= %s \n", functionName, groupName.c_str() ); // Create a new XPS axis GluexXPSAxis* newAxisPtr = new GluexXPSAxis( this, axis, positionerName.c_str(), 1. / stepSize ); // if the appropriate group exists then add ths axis to its group object. string groupName = newAxisPtr->getGroupName(); if( gxcGroupMap.count( groupName ) > 0 ) { gxcGroupMap[groupName]->addAxis( positionerName, newAxisPtr ); } this->unlock(); return newAxisPtr; } GluexXPSGroup* GluexXPSController::addGroup( const std::string pName, const std::string groupName ) { const char *functionName = "addGroup"; if( gxcGroupMap.count(groupName) > 0 ) { asynPrint( this->pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: group already exists\n", driverName, functionName ); return 0; } GluexXPSGroup* newGroup = new GluexXPSGroup( pName, groupName, this ); if( newGroup != 0 ) { this->lock(); gxcGroupMap[groupName] = newGroup; this->unlock(); } return newGroup; } /* added for PCO functions */ asynStatus GluexXPSController::writeFloat64( asynUser *pasynUser, epicsFloat64 value ) { int function = pasynUser->reason; int status = asynSuccess; // static const char *functionName = "writeFloat64"; GluexXPSAxis* pAxis = dynamic_cast( this->getAxis( pasynUser ) ); if ( !pAxis ) return asynError; /* Set the parameter and readback in the parameter library. */ status = pAxis->setDoubleParam( function, value ); int axis = pAxis->axisNo_; if ( function == pcoMinPosition_ ) { pAxis->pcoMinPosSet_ = value; } else if ( function == pcoMaxPosition_ ) { pAxis->pcoMaxPosSet_ = value; } else if ( function == pcoPositionStep_ ) { pAxis->pcoStepSet_ = value; } else if ( function == positionerReferencingParameter_ ) { setDoubleParam( axis, positionerReferencingParameter_, value ); } else { /* Call base class method */ status = XPSController::writeFloat64( pasynUser, value ); } return (asynStatus) status; } asynStatus GluexXPSController::writeInt32( asynUser *pasynUser, epicsInt32 value ) { int function = pasynUser->reason; int status = asynSuccess; int axis; // char groupName[MAX_GROUPNAME_LEN]; GluexXPSAxis* pAxis = dynamic_cast( this->getAxis( pasynUser ) ); if ( !pAxis ) return asynError; axis = pAxis->axisNo_; /* Set the parameter and readback in the parameter library. This may be overwritten when we read back the * status at the end, but that's OK */ status = pAxis->setIntegerParam( function, value ); // getStringParam(XPSReferencingGroupName_, (int)sizeof(groupName), groupName); // printf("********* Referencing groupName= %s \n", groupName); if ( function == pcoSet_ ) { status = setPco( axis ); } else if ( function == pcoEnable_ ) { status = enablePco( axis ); } else if ( function == pcoDisable_ ) { status = disablePco( axis ); } else if ( function == pcoPulseWidth_ ) { switch ( value ) { case 0: pAxis->pcoPulseWidthSet_ = 0.2; break; case 1: pAxis->pcoPulseWidthSet_ = 1.; break; case 2: pAxis->pcoPulseWidthSet_ = 2.5; break; case 3: pAxis->pcoPulseWidthSet_ = 10.; break; default: pAxis->pcoPulseWidthSet_ = 0.2; break; } } else if ( function == encoderSettlingTime_ ) { switch ( value ) { case 0: pAxis->encoderSettlingTimeSet_ = 0.075; break; case 1: pAxis->encoderSettlingTimeSet_ = 1.; break; case 2: pAxis->encoderSettlingTimeSet_ = 4; break; case 3: pAxis->encoderSettlingTimeSet_ = 12.; break; default: pAxis->encoderSettlingTimeSet_ = 0.075; break; } ////---------- Sensor for positionerReferencingActionExecute ---------- // } else if (function == positionerReferencingSensor_) { // map referenceSensorStringValue = map_list_of // ( 0, "MinusEndOfRun" ) ( 1, "MechanicalZero" ) // ( 2, "PlusEndOfRun" ) ( 3, "None" ); // if( referenceSensorStringValue.count(value) > 0 ) // setStringParam( axis, positionerReferencingSensor_, referenceSensorStringValue[value].c_str() ); ////--------- Action for positionerReferencingActionExecute --------- // } else if (function == positionerReferencingAction_) { // map referenceActionStringValue = map_list_of // (0, "LatchOnLowToHighTransition" ) (1, "LatchOnHighToLowTransition") // (2, "LatchOnIndex") (3, "LatchOnIndexAfterSensorHighToLowTransition") // (4, "SetPosition") (5, "SetPositionToHomePreset") // (6, "MoveToPreviouslyLatchedPosition") (7, "MoveRelative") ; // if( referenceActionStringValue.count(value) > 0 ) // setStringParam( axis, positionerReferencingAction_, referenceActionStringValue[value].c_str() ); } else if (function == positionerReferencingActionExecute_) { status = pAxis->referencingActionExecute(); } else { /* Call base class method */ status = XPSController::writeInt32( pasynUser, value ); } return (asynStatus) status; } /* Function to get PCO (Position Compare Output) parameters */ asynStatus GluexXPSController::getPco( size_t axis ) { int status; int enableDisableState = 2; bool enableState; bool pcoGetOK = true; char message[MAX_MESSAGE_LEN] = " "; double minPositionActual; double maxPositionActual; double positionStepActual; double pulseWidthActual; double encoderSettlTimeActual; static const char *functionName = "getPco"; GluexXPSAxis* pAxis = dynamic_cast( this->getAxis( axis ) ); asynPrint( this->pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s: entry\n", driverName, functionName ); /* Get configured parameters of the PCO*/ status = PositionerPositionCompareGet( pAxis->pollSocket_, pAxis->positionerName_, &minPositionActual, &maxPositionActual, &positionStepActual, &enableState ); if ( status ) pcoGetOK = false; switch ( -status ) { case 0: enableDisableState = enableState; pAxis->setDoubleParam( pcoMinPositionActual_, minPositionActual ); pAxis->setDoubleParam( pcoMaxPositionActual_, maxPositionActual ); pAxis->setDoubleParam( pcoPositionStepActual_, positionStepActual ); pAxis->setIntegerParam( pcoEnableDisableState_, enableDisableState ); break; case 8: strcpy( message, " Check the position encoder\n 'AquadB' or 'AnalogInterpolated'" ); break; case 23: strcpy( message, " Check the parameters \n Must be configured" ); break; case 21: strcpy( message, "XPS initialization in progress" ); break; default: sprintf( message, "Unknown PositionerPositionCompareGet error=%d", status ); break; } /* Get PCO pulse parameters*/ status = PositionerPositionComparePulseParametersGet( pAxis->pollSocket_, pAxis->positionerName_, &pulseWidthActual, &encoderSettlTimeActual ); if ( status ) pcoGetOK = false; switch ( -status ) { case 0: if ( !(pulseWidthActual == 0.2 || pulseWidthActual == 1. || pulseWidthActual == 2.5 || pulseWidthActual == 10.) ) { strcpy( message, " Check the Pulse Width \n Must be 0.2, 1, 2.5 or 10" ); } if ( !(encoderSettlTimeActual == 0.075 || encoderSettlTimeActual == 1. || encoderSettlTimeActual == 4. || encoderSettlTimeActual == 12.) ) { strcpy( message, " Check the EncoderSettlingTime \n Must be 0.075, 1, 4 or 12" ); } pAxis->setDoubleParam( pcoPulseWidthActual_, pulseWidthActual ); pAxis->setDoubleParam( encoderSettlingTimeActual_, encoderSettlTimeActual ); break; case 8: strcpy( message, " Check the positioner\n Must not be secondary" ); break; case 21: strcpy( message, "XPS initialization in progress" ); break; default: sprintf( message, "Unknown PositionerPositionComparePulseParametersGet error=%d", status ); break; } pAxis->setStringParam( pcoGetMessage_, message ); pAxis->setStringParam( pcoPositionerName_, pAxis->positionerName_ ); callParamCallbacks(); return pcoGetOK ? asynError : asynSuccess; } /* Function to set PCO (Position Compare Output) parameters */ asynStatus GluexXPSController::setPco( size_t axis ) { int status; bool pcoSetOK = true; char message[MAX_MESSAGE_LEN]; int setStatus; static const char *functionName = "setPco"; GluexXPSAxis* pAxis = dynamic_cast( this->getAxis( axis ) ); asynPrint( this->pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s: entry\n", driverName, functionName ); status = PositionerPositionComparePulseParametersSet( pAxis->pollSocket_, pAxis->positionerName_, pAxis->pcoPulseWidthSet_, pAxis->encoderSettlingTimeSet_ ); switch ( -status ) { case 0: strcpy( message, " " ); break; case 8: strcpy( message, "Set: Check the position type\n Must not be a secondary" ); break; case 17: strcpy( message, "Set: Check parameter values\n PulseWidth and EncodrSettlingTime" ); break; case 21: strcpy( message, "Set: XPS initialization in progress" ); break; case 22: strcpy( message, "Set: Check PCO state\n Must be disabled " ); break; case 24: strcpy( message, "Set: Check the position encoder\n 'AquadB' or 'AnalogInterpolated'" ); break; case 115: strcpy( message, "Set: Check if the CIE board supports this function" ); break; default: sprintf( message, "Set: Unknown PositionerPositionComparePulseParametersSet error=%d", status ); break; } if ( status ) goto done; status = PositionerPositionCompareSet( pAxis->pollSocket_, pAxis->positionerName_, pAxis->pcoMinPosSet_, pAxis->pcoMaxPosSet_, pAxis->pcoStepSet_ ); if ( status ) pcoSetOK = false; switch ( -status ) { case 0: strcpy( message, " " ); break; case 8: strcpy( message, "Set: Check the position encoder\n 'AquadB' or 'AnalogInterpolated'" ); break; case 17: if ( pAxis->pcoMinPosSet_ >= pAxis->pcoMaxPosSet_ ) { strcpy( message, "Set: Check parameter values\n MinPos < MaxPos ?" ); } if ( pAxis->pcoStepSet_ < 0 ) { strcpy( message, "Set: Check parameter values\n Step > 0 ?" ); } if ( (pAxis->pcoMinPosSet_ < pAxis->pcoMaxPosSet_) && (pAxis->pcoStepSet_ > (pAxis->pcoMaxPosSet_ - pAxis->pcoMinPosSet_)) ) { strcpy( message, "Set: Check parameter values\n Step size is too large" ); } break; case 21: strcpy( message, "Set: XPS initialization in progress" ); break; case 22: strcpy( message, "Set: Check PCO state\n Must be disabled " ); break; case 24: strcpy( message, "Set: No position encoder" ); break; default: sprintf( message, "Set: Unknown PositionerPositionCompareSet error=%d", status ); break; } done: pAxis->setStringParam( pcoMessage_, message ); pAxis->setStringParam( pcoSetMessage_, message ); strcpy( message, " " ); pAxis->setStringParam( pcoEnableMessage_, message ); pAxis->setStringParam( pcoDisableMessage_, message ); setStatus = (pcoSetOK) ? PCO_STATUS_SUCCESS : PCO_STATUS_FAILURE; pAxis->setIntegerParam( pcoSetStatus_, setStatus ); pAxis->setIntegerParam( pcoSet_, 0 ); callParamCallbacks(); return status ? asynError : asynSuccess; } /* Function to enable PCO */ asynStatus GluexXPSController::enablePco( size_t axis ) { int status; bool pcoEnableOK = true; char message[MAX_MESSAGE_LEN]; int enableStatus; static const char *functionName = "enablePco"; GluexXPSAxis* pAxis = dynamic_cast( this->getAxis( axis ) ); asynPrint( this->pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s: entry\n", driverName, functionName ); status = PositionerPositionCompareEnable( pAxis->pollSocket_, pAxis->positionerName_ ); if ( status ) pcoEnableOK = false; switch ( -status ) { case 0: strcpy( message, " " ); pAxis->setIntegerParam( pcoEnableDisableState_, 1 ); break; case 8: strcpy( message, "Enable: Check the position encoder\n 'AquadB' or 'AnalogInterpolated'" ); break; case 21: strcpy( message, "Enable: XPS initialization in progress" ); break; case 22: strcpy( message, "Enable: Positioner is not ready" ); break; default: sprintf( message, "Enable: Unknown PositionerPositionCompareEnable error=%d", status ); break; } pAxis->setStringParam( pcoMessage_, message ); pAxis->setStringParam( pcoEnableMessage_, message ); strcpy( message, " " ); pAxis->setStringParam( pcoSetMessage_, message ); pAxis->setStringParam( pcoDisableMessage_, message ); enableStatus = (pcoEnableOK) ? PCO_STATUS_SUCCESS : PCO_STATUS_FAILURE; pAxis->setIntegerParam( pcoEnableStatus_, enableStatus ); pAxis->setIntegerParam( pcoEnable_, 0 ); callParamCallbacks(); return status ? asynError : asynSuccess; } /* Function to disable PCO */ asynStatus GluexXPSController::disablePco( size_t axis ) { int status; bool pcoDisableOK = true; char message[MAX_MESSAGE_LEN]; int disableStatus; static const char *functionName = "disablePco"; GluexXPSAxis* pAxis = dynamic_cast( this->getAxis( axis ) ); asynPrint( this->pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s: entry\n", driverName, functionName ); status = PositionerPositionCompareDisable( pAxis->pollSocket_, pAxis->positionerName_ ); if ( status ) pcoDisableOK = false; switch ( -status ) { case 0: strcpy( message, " " ); pAxis->setIntegerParam( pcoEnableDisableState_, 0 ); break; case 8: strcpy( message, "Disable: Check the position encoder\n 'AquadB' or 'AnalogInterpolated'" ); break; case 21: strcpy( message, "Disable: XPS initialization in progress" ); break; default: sprintf( message, "Disable: Unknown PositionerPositionCompareDisable error=%d", status ); break; } pAxis->setStringParam( pcoMessage_, message ); pAxis->setStringParam( pcoDisableMessage_, message ); strcpy( message, " " ); pAxis->setStringParam( pcoSetMessage_, message ); pAxis->setStringParam( pcoEnableMessage_, message ); pAxis->setStringParam( pcoDisableMessage_, message ); disableStatus = (pcoDisableOK) ? PCO_STATUS_SUCCESS : PCO_STATUS_FAILURE; pAxis->setIntegerParam( pcoDisableStatus_, disableStatus ); pAxis->setIntegerParam( pcoDisable_, 0 ); callParamCallbacks(); return status ? asynError : asynSuccess; } //---------------------------------------------------------------------------------- asynStatus GluexXPSController::getPositionerErrorAndHardwareStatus(size_t axis) { int status; char hardwareStatusString[MAX_MESSAGE_LEN]; char errorString[MAX_MESSAGE_LEN]; int positionerError; int positionerHardwareStatus; GluexXPSAxis* pAxis = dynamic_cast( this->getAxis( axis ) ); /* --- get positionerError */ status = PositionerErrorRead(pAxis->pollSocket_, pAxis->positionerName_, &positionerError); // printf("*********positionerReferencingActionExecute_ groupName= %s positionerName= %s\n", groupName,pAxis->positionerName_); if (status != 0) { asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, " Error performing PositionerErrorRead, status=%d\n", status); return asynError; } setIntegerParam(axis, positionerError_, positionerError); /* --- get positionerErrorString */ status = PositionerErrorStringGet(pAxis->pollSocket_, positionerError,errorString); setStringParam(axis, positionerErrorString_, errorString); /* printf(" status= %d pAxis->positionerName= %s positionerError=%i errorString= %s \n", status,pAxis->positionerName_, positionerError,errorString); */ /* --- get positionerHardwareStatus */ status = PositionerHardwareStatusGet(pAxis->pollSocket_, pAxis->positionerName_,&positionerHardwareStatus); if (status != 0) { asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, " Error performing PositionerHardwareStatusGet, status=%d\n", status); return asynError; } setIntegerParam(axis, positionerHardwareStatus_, positionerHardwareStatus); /* --- get positionerHardwareStatusString */ status = PositionerHardwareStatusStringGet(pAxis->pollSocket_, positionerHardwareStatus,hardwareStatusString); setStringParam( axis, positionerHardwareStatusString_, hardwareStatusString); callParamCallbacks(); return asynSuccess; } //---------------------------------------------------------------------------------- asynStatus GluexXPSController::getPositionerStageParameters(size_t axis) { int status; char homeSMVel[] = "HomeSearchMaximumVelocity"; char homePS[] = "HomePreset"; char homeSearchMaxVel[30], homePreset[30]; double homeSearchMaxVel_d,homePreset_d; GluexXPSAxis* pAxis = dynamic_cast( this->getAxis( axis ) ); /* Read HomeSearchMaxVelocity from the controller for this axis */ status = PositionerStageParameterGet(pAxis->pollSocket_, pAxis->positionerName_, homeSMVel, homeSearchMaxVel); if (status != 0) { asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, " Error performing PositionerStageParameterGet %s status=%d\n",homeSMVel, status); return asynError; } homeSearchMaxVel_d = atof(homeSearchMaxVel); // cout << " Positioner: " << pAxis->positionerName_ << " , homeSearchMaxVel= " << homeSearchMaxVel<< " == "<pollSocket_, pAxis->positionerName_, homePS, homePreset); if (status != 0) { asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, " Error performing PositionerStageParameterGet %s status=%d\n",homePS, status); return asynError; } homePreset_d = atof(homePreset); setDoubleParam( axis, positionerHomePreset_, homePreset_d); // cout << " Positioner: " << pAxis->positionerName_ <<" , "<< homePS<<"= "<< homePreset <<" == "<addAxis( axis, positionerName, stepSize ); if ( axisPtr == 0 ) return asynError; // pC->lock(); // new GluexXPSAxis(pC, axis, positionerName, 1./stepSize); // pC->unlock(); return asynSuccess; } asynStatus GluexXPSCreateProfile( const char *XPSName, /* specify which controller by port name */ int maxPoints, /* maximum number of profile points */ const char *ftpUsername, /* FTP account name */ const char *ftpPassword ) /* FTP password */ { GluexXPSController *pC; static const char *functionName = "GluexXPSCreateProfile"; pC = (GluexXPSController*) findAsynPortDriver( XPSName ); if ( !pC ) { printf( "%s:%s: Error port %s not found\n", driverName, functionName, XPSName ); return asynError; } pC->lock(); pC->initializeProfile( maxPoints, ftpUsername, ftpPassword ); pC->unlock(); return asynSuccess; } asynStatus GluexXPSDisableAutoEnable( const char *XPSName ) { GluexXPSController *pC; static const char *functionName = "GluexXPSDisableAutoEnable"; pC = (GluexXPSController*) findAsynPortDriver( XPSName ); if ( !pC ) { printf( "%s:%s: Error port %s not found\n", driverName, functionName, XPSName ); return asynError; } return pC->disableAutoEnable(); } asynStatus GluexXPSNoDisableError( const char *XPSName ) { GluexXPSController *pC; static const char *functionName = "GluexXPSNoDisableError"; pC = (GluexXPSController*) findAsynPortDriver( XPSName ); if ( !pC ) { printf( "%s:%s: Error port %s not found\n", driverName, functionName, XPSName ); return asynError; } return pC->noDisableError(); } /* Code for iocsh registration */ /* GluexXPSCreateController */ static const iocshArg GluexXPSCreateControllerArg0 = { "Controller port name", iocshArgString }; static const iocshArg GluexXPSCreateControllerArg1 = { "IP address", iocshArgString }; static const iocshArg GluexXPSCreateControllerArg2 = { "IP port", iocshArgInt }; static const iocshArg GluexXPSCreateControllerArg3 = { "Number of axes", iocshArgInt }; static const iocshArg GluexXPSCreateControllerArg4 = { "Moving poll rate (ms)", iocshArgInt }; static const iocshArg GluexXPSCreateControllerArg5 = { "Idle poll rate (ms)", iocshArgInt }; static const iocshArg GluexXPSCreateControllerArg6 = { "Enable set position", iocshArgInt }; static const iocshArg GluexXPSCreateControllerArg7 = { "Set position settling time (ms)", iocshArgInt }; static const iocshArg * const GluexXPSCreateControllerArgs[] = { &GluexXPSCreateControllerArg0, &GluexXPSCreateControllerArg1, &GluexXPSCreateControllerArg2, &GluexXPSCreateControllerArg3, &GluexXPSCreateControllerArg4, &GluexXPSCreateControllerArg5, &GluexXPSCreateControllerArg6, &GluexXPSCreateControllerArg7 }; static const iocshFuncDef configGluexXPS = { "GluexXPSCreateController", 8, GluexXPSCreateControllerArgs }; static void configGluexXPSCallFunc( const iocshArgBuf *args ) { GluexXPSCreateController( args[0].sval, args[1].sval, args[2].ival, args[3].ival, args[4].ival, args[5].ival, args[6].ival, args[7].ival ); } /* GluexXPSCreateAxis */ static const iocshArg GluexXPSCreateAxisArg0 = { "Controller port name", iocshArgString }; static const iocshArg GluexXPSCreateAxisArg1 = { "Axis number", iocshArgInt }; static const iocshArg GluexXPSCreateAxisArg2 = { "Axis name", iocshArgString }; static const iocshArg GluexXPSCreateAxisArg3 = { "Steps per unit", iocshArgString }; static const iocshArg * const GluexXPSCreateAxisArgs[] = { &GluexXPSCreateAxisArg0, &GluexXPSCreateAxisArg1, &GluexXPSCreateAxisArg2, &GluexXPSCreateAxisArg3 }; static const iocshFuncDef configGluexXPSAxis = { "GluexXPSCreateAxis", 4, GluexXPSCreateAxisArgs }; static void configGluexXPSAxisCallFunc( const iocshArgBuf *args ) { GluexXPSCreateAxis( args[0].sval, args[1].ival, args[2].sval, args[3].sval ); } /* GluexXPSCreateProfile */ static const iocshArg GluexXPSCreateProfileArg0 = { "Controller port name", iocshArgString }; static const iocshArg GluexXPSCreateProfileArg1 = { "Max points", iocshArgInt }; static const iocshArg GluexXPSCreateProfileArg2 = { "FTP username", iocshArgString }; static const iocshArg GluexXPSCreateProfileArg3 = { "FTP password", iocshArgString }; static const iocshArg * const GluexXPSCreateProfileArgs[] = { &GluexXPSCreateProfileArg0, &GluexXPSCreateProfileArg1, &GluexXPSCreateProfileArg2, &GluexXPSCreateProfileArg3 }; static const iocshFuncDef configGluexXPSProfile = { "GluexXPSCreateProfile", 4, GluexXPSCreateProfileArgs }; static void configGluexXPSProfileCallFunc( const iocshArgBuf *args ) { GluexXPSCreateProfile( args[0].sval, args[1].ival, args[2].sval, args[3].sval ); } /* GluexXPSDisableAutoEnable */ static const iocshArg GluexXPSDisableAutoEnableArg0 = { "Controller port name", iocshArgString }; static const iocshArg * const GluexXPSDisableAutoEnableArgs[] = { &GluexXPSDisableAutoEnableArg0 }; static const iocshFuncDef disableGluexAutoEnable = { "GluexXPSDisableAutoEnable", 1, GluexXPSDisableAutoEnableArgs }; static void disableGluexAutoEnableCallFunc( const iocshArgBuf *args ) { GluexXPSDisableAutoEnable( args[0].sval ); } /* GluexXPSNoDisableError */ static const iocshArg GluexXPSNoDisableErrorArg0 = { "Controller port name", iocshArgString }; static const iocshArg * const GluexXPSNoDisableErrorArgs[] = { &GluexXPSNoDisableErrorArg0 }; static const iocshFuncDef noGluexDisableError = { "GluexXPSNoDisableError", 1, GluexXPSNoDisableErrorArgs }; static void noGluexDisableErrorCallFunc( const iocshArgBuf *args ) { GluexXPSNoDisableError( args[0].sval ); } static void GluexXPSRegister3( void ) { iocshRegister( &configGluexXPS, configGluexXPSCallFunc ); iocshRegister( &configGluexXPSAxis, configGluexXPSAxisCallFunc ); iocshRegister( &configGluexXPSProfile, configGluexXPSProfileCallFunc ); iocshRegister( &disableGluexAutoEnable, disableGluexAutoEnableCallFunc ); iocshRegister( &noGluexDisableError, noGluexDisableErrorCallFunc ); } epicsExportRegistrar(GluexXPSRegister3); } // extern "C"