/* * boardAsynPar.hh * * Created on: February 18, 2015 * Author: Hovanes Egiyan * * This file defines an augmenting class for asynDrvBoard to keep track of asyn parameters. * Some of the methods of this class expect to receive the pointer of the asynDrvBoard object * for which the parameter instance is used for. So, this class is very much tied to the * asynDrvBoard class and should not be considered as "an" independent class, these objects expect * to be members of asynDrvBoard class object. */ #ifndef __BOARD_ASYNPAR_HH__ #define __BOARD_ASYNPAR_HH__ /************/ /* Includes */ /************/ #include #include #include #include #include #include /* EPICS includes */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "new" #include "boost/function.hpp" #include "boost/bind.hpp" #include "asynDrvBoard.hh" #include "MtxLock.hh" #include "MutexedClass.hh" #include "boardVAsynPar.hh" // Template class for asyn parameters. For different parameters types we will // use specialized methods for particular variable types. This class inherits // from the virtual base class. template class boardAsynPar: public boardVAsynPar { protected: VarType bapValue; // Parameter value // Read function boost::function bapReadFunc; // Write function boost::function bapWriteFunc; // Alarms status function boost::function bapAlarmStatusFunc; // Alarms severity function boost::function bapAlarmSeverityFunc; public: // Default constructor boardAsynPar() : bapValue() { return;} // Main constructor boardAsynPar(string parName, int parNum, boost::function readFun, boost::function writeFun, epicsUInt32 mask = boardVAsynPar::bvapAllBitMask); virtual ~boardAsynPar() { return; } // Copy constructor boardAsynPar(const boardAsynPar& par); // Copy operator virtual boardAsynPar& operator=( const boardAsynPar& argPar); // Method to create the parameter for the driver passed by the argument. // This method is expected to be called from the AsynDriver constructor virtual void Connect2Driver(asynDrvBoard* driver); virtual asynStatus Write(asynDrvBoard* driver, unsigned channel, void* valPtr = 0, epicsUInt32 mask = boardVAsynPar::bvapAllBitMask); // Virtual Write asyn parameter virtual asynStatus Read(asynDrvBoard* driver, unsigned channel, void* valPtr = 0, epicsUInt32* mask = 0); // Virtual Read asyn parameter virtual asynStatus WriteTmpl(asynDrvBoard* driver, unsigned channel, void* valPtr = 0, epicsUInt32 mask = boardVAsynPar::bvapAllBitMask); // Write asyn parameter virtual asynStatus ReadTmpl(asynDrvBoard* driver, unsigned channel, void* valPtr = 0, epicsUInt32* mask = 0); // Read asyn parameter virtual VarType GetValue() ; virtual VarType SetValue(const VarType value) ; virtual boost::function GetReadFunc() ; virtual boost::function GetWriteFunc() ; virtual boost::function GetAlarmStatusFunc() ; virtual boost::function GetAlarmSeverityFunc() ; virtual void SetAlarmStatusFunc(boost::function& func) ; virtual void SetAlarmSeverityFunc(boost::function& func) ; }; // Template class for asyn unsigned parameters. This class inherits // from the double-template class base class and is a partial specialization for epicsUInt32. template class boardAsynParUInt32 : public boardAsynPar { public: boardAsynParUInt32(string parName, int parNum, boost::function readFun, boost::function writeFun, epicsUInt32 mask = boardVAsynPar::bvapAllBitMask ); virtual ~boardAsynParUInt32() {; } // Method to create the parameter for the driver passed by the argument. // This method is expected to be called from the AsynDriver constructor virtual void Connect2Driver(asynDrvBoard* driver); virtual asynStatus WriteTmpl(asynDrvBoard* driver, unsigned channel, void* valPtr = 0, epicsUInt32 mask = boardVAsynPar::bvapAllBitMask); // Write asyn parameter virtual asynStatus ReadTmpl(asynDrvBoard* driver, unsigned channel, void* valPtr = 0, epicsUInt32* mask = 0); // Read asyn parameter }; // Template class for asyn double parameters. This class inherits // from the double-template class base class and is a partial specialization for epicsUInt32. template class boardAsynParDouble : public boardAsynPar { public: boardAsynParDouble(string parName, int parNum, boost::function readFun, boost::function writeFun, epicsUInt32 mask = boardVAsynPar::bvapAllBitMask ); virtual ~boardAsynParDouble() {; } // Method to create the parameter for the driver passed by the argument. // This method is expected to be called from the AsynDriver constructor virtual void Connect2Driver(asynDrvBoard* driver); virtual asynStatus WriteTmpl(asynDrvBoard* driver, unsigned channel, void* valPtr = 0, epicsUInt32 mask = boardVAsynPar::bvapAllBitMask); // Write asyn parameter virtual asynStatus ReadTmpl(asynDrvBoard* driver, unsigned channel, void* valPtr = 0, epicsUInt32* mask = 0); // Read asyn parameter }; //======================================================================== // Implementation for double template class boardAsynPar //======================================================================== // Main constructor template boardAsynPar::boardAsynPar(string parName, int parNum, boost::function readFun, boost::function writeFun, epicsUInt32 mask ) : boardVAsynPar(parName, parNum, mask), bapValue(), bapReadFunc(readFun), bapWriteFunc(writeFun) { cout << "Created boardAsynPar " << this->GetName() << endl; return; } // Copy constructor template boardAsynPar::boardAsynPar( const boardAsynPar& par) : boardVAsynPar(par), bapValue(par.GetValue(), bapReadFunc(par.GetReadFunc()), bapWriteFunc(par.GetWriteFunc() ) ) { return; } // Method to create the parameter for the driver passed by the argument. // This method is expected to be called from the AsynDriver constructor template void boardAsynPar::Connect2Driver( asynDrvBoard* driver) { throw std::runtime_error("boardAsynPar: Must use a specialized Connect2Driver method"); } template asynStatus boardAsynPar::Write( asynDrvBoard* driver, unsigned channel, void* valPtr, epicsUInt32 mask) // Virtual Write asyn parameter { return this->WriteTmpl(driver, channel, valPtr, mask); } template asynStatus boardAsynPar::Read( asynDrvBoard* driver, unsigned channel, void* valPtr, epicsUInt32* mask) // Virtual Read asyn parameter { return this->ReadTmpl(driver, channel, valPtr, mask); } template asynStatus boardAsynPar::WriteTmpl( asynDrvBoard* driver, unsigned channel, void* valPtr, epicsUInt32 mask) // Write asyn parameter { throw std::runtime_error("boardAsynPar: Must use a specialized Write method"); } template asynStatus boardAsynPar::ReadTmpl( asynDrvBoard* driver, unsigned channel, void* valPtr, epicsUInt32* mask) // Read asyn parameter { throw std::runtime_error("boardAsynPar: Must use a specialized Read method"); } template boardAsynPar& boardAsynPar::operator=( const boardAsynPar& argPar) { boardAsynPar& par = const_cast&>(argPar); boardVAsynPar* baseClassPtr = dynamic_cast*>(this); baseClassPtr->operator=(par); MtxLock selfObjLock(this->mcMutex); MtxLock otherObjLock(par.mcMutex); bapValue = par.bapValue; return *this; } template inline VarType boardAsynPar::GetValue() { MtxLock objLock(this->mcMutex); return bapValue; } template inline VarType boardAsynPar::SetValue( const VarType value) { MtxLock objLock(this->mcMutex); return (bapValue = value); } template inline boost::function boardAsynPar::GetReadFunc() { MtxLock objLock(this->mcMutex); return bapReadFunc; } template inline boost::function boardAsynPar::GetWriteFunc() { MtxLock objLock(this->mcMutex); return bapWriteFunc; } template inline boost::function boardAsynPar::GetAlarmStatusFunc() { MtxLock objLock(this->mcMutex); return bapAlarmStatusFunc; } template inline boost::function boardAsynPar::GetAlarmSeverityFunc() { MtxLock objLock(this->mcMutex); return bapAlarmSeverityFunc; } template void boardAsynPar::SetAlarmStatusFunc( boost::function& func ) { MtxLock objLock(this->mcMutex); bapAlarmStatusFunc = func; } template void boardAsynPar::SetAlarmSeverityFunc( boost::function& func ) { MtxLock objLock(this->mcMutex); bapAlarmSeverityFunc = func; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Below are the implementation of partially specialized classes ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //========================================================================================================== // Specialized for unsigned type parameters //========================================================================================================== template boardAsynParUInt32::boardAsynParUInt32(string parName, int parNum, boost::function readFun, boost::function writeFun, epicsUInt32 mask ) : boardAsynPar( parName, parNum, readFun, writeFun, mask ) { boost::function tmpFunc = readFun; cout << "Received read function " << readFun << endl; cout << "Kept read function " << this->bapReadFunc << endl; cout << "Test Func is " << tmpFunc << endl; return; } // Specialized method for UInt32 to create the parameter for the driver passed by the argument. // This method is expected to be called from the AsynDriver constructor template void boardAsynParUInt32::Connect2Driver( asynDrvBoard* driver ) { // cout << "Inside boardAsynPar::Connect2Driver" << endl; MtxLock objLock(this->mcMutex); driver->createParam( this->bvapParName.c_str(), asynParamUInt32Digital, &this->bvapParNum ) ; return; } // Specialized for UInt32 method to write asyn parameter template asynStatus boardAsynParUInt32::WriteTmpl( asynDrvBoard* driver, unsigned channel, void* valPtr, epicsUInt32 mask) { // cout << "Inside boardAsynParUInt32>::WriteTmpl" << endl; // BoardClass* board = driver->getBoard(); MtxLock objLock(this->mcMutex); asynStatus aStat = asynError; epicsUInt32 value = *static_cast(valPtr); cout << "Setting UInt32 parameter " << this->bvapParName << " to " << value << endl; // this->bapWriteFunc( channel, value ); // ( (*board).*(this->bvapWriteFun) ) ( value ); aStat = driver->setUIntDigitalParam(channel, this->bvapParNum, value, mask, mask); return aStat; } // Specialized for UInt32 to read asyn parameter template asynStatus boardAsynParUInt32::ReadTmpl( asynDrvBoard* driver, unsigned channel, void* valPtr, epicsUInt32* mask) { cout << "Inside boardAsynParUInt32::ReadTmpl" << endl; // BoardClass* board = driver->getBoard(); MtxLock objLock(this->mcMutex); asynStatus aStat = asynError; cout << "Calling read function for parameter " << this->bvapParName << endl; // this->bapValue = ((*board).*(this->bvapReadFun))(); this->bapValue = this->bapReadFunc(channel); cout << "Setting Digital param" << endl; aStat = driver->setUIntDigitalParam(channel, this->bvapParNum, this->bapValue, *mask, *mask); *(static_cast(valPtr)) = this->bapValue; return aStat; } //========================================================================================================== // Specialized for double type parameters //========================================================================================================== template boardAsynParDouble::boardAsynParDouble(string parName, int parNum, boost::function readFun, boost::function writeFun, epicsUInt32 mask ) : boardAsynPar( parName, parNum, readFun, writeFun, mask ) { cout << "Received read function " << readFun << endl; cout << "Kept read function " << this->bapReadFunc << endl; return; } // Specialized method for Double to create the parameter for the driver passed by the argument. // This method is expected to be called from the AsynDriver constructor template void boardAsynParDouble::Connect2Driver( asynDrvBoard* driver ) { // cout << "Inside boardAsynPar::Connect2Driver" << endl; MtxLock objLock(this->mcMutex); driver->createParam( this->bvapParName.c_str(), asynParamFloat64, &this->bvapParNum ) ; return; } // Specialized for double method to write asyn parameter template asynStatus boardAsynParDouble::WriteTmpl( asynDrvBoard* driver, unsigned channel, void* valPtr, epicsUInt32 mask) { // cout << "Inside boardAsynParDouble>::WriteTmpl" << endl; // BoardClass* board = driver->getBoard(); MtxLock objLock(this->mcMutex); asynStatus aStat = asynError; epicsFloat64 value = *static_cast(valPtr); cout << "Setting epicsFloat64 parameter " << this->bvapParName << " to " << value << endl; // this->bapWriteFunc( channel, value ); // ( (*board).*(this->bvapWriteFun) ) ( value ); aStat = driver->setDoubleParam(channel, this->bvapParNum, value ); return aStat; } // Specialized for UInt32 to read asyn parameter template asynStatus boardAsynParDouble::ReadTmpl( asynDrvBoard* driver, unsigned channel, void* valPtr, epicsUInt32* mask) { // BoardClass* board = driver->getBoard(); MtxLock objLock(this->mcMutex); asynStatus aStat = asynError; // if( this->bapValue ) { // this->bapValue = this->bapReadFunc(channel); // } this->bapValue = this->bapReadFunc(channel); aStat = driver->setDoubleParam(channel, this->bvapParNum, this->bapValue ); // Set the alarm status and severity for this parameter if( ! this->bapAlarmStatusFunc.empty() ) { aStat = driver->setParamAlarmStatus(channel, this->bvapParNum, this->bapAlarmStatusFunc(channel) ); } if( ! this->bapAlarmSeverityFunc.empty() ) { aStat = driver->setParamAlarmSeverity(channel, this->bvapParNum, this->bapAlarmSeverityFunc(channel) ); } *(static_cast(valPtr)) = this->bapValue; return aStat; } #endif /* __BOARD_ASYNPAR_HH__ */