/* Copyright (c) 20011 Hovanes Egiyan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "devBaseIU.hh" //---------------------------------------------------------------------- // record processing routines //---------------------------------------------------------------------- // ai record static long basesAiInit(struct aiRecord* pai) { cout << "Initializing AI for " << pai->name << endl; pai->dpvt = NULL; try { BaseIUInput* inPars = new BaseIUInput( string(pai->inp.value.instio.string)); //! Bus number cannot be negative cout << "Port Name is " << inPars->GetPort() << endl; if (inPars->GetPort() == "") { stringstream errStream; errStream << "devAiBaseIU (basesAiInit): bad port name " << inPars->GetPort(); RecordError recError(reinterpret_cast(pai), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } //! Address must be positive integer if (inPars->GetAddress() <= 0) { stringstream errStream; errStream << "devAiBaseIU (basesAiInit): bad board address " << inPars->GetAddress(); RecordError recError(reinterpret_cast(pai), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } //! We use ai records for ADC type parameters only cout << "Parameter type is " << inPars->GetParType() << endl; if (inPars->GetParType() != string("ADC")) { stringstream errStream; errStream << "devAiBaseIU (basesAiInit): bad parameter type " << inPars->GetParType(); RecordError recError(reinterpret_cast(pai), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } //! save the address of the input object pai->dpvt = static_cast(inPars); } //! If there was a thrown exception set disable alarm status with invalid severity //! and disable the record catch (BaseIUInput::BadString & excpt) { cout << "Caugth a problem" << endl; string errString = string("devAiBaseIU (basesAiInit): ") + excpt.GetMessage(); RecordError recError(reinterpret_cast(pai), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } pai->udf = false; cout << "AI initialized" << endl; return statOK; } static long basesAiRead(struct aiRecord* pai) { //! Find the pointer of the input object BaseIUInput* inPars = 0; if (pai->dpvt == NULL) { string errString = "devAiBaseIU (basesAiRead) : driver error"; RecordError recError(reinterpret_cast(pai), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } else inPars = static_cast(pai->dpvt); // BaseIUBus* bus = BaseIUMgr::bmgBusMap[inPars->GetPort()].second; BaseIUVirtBus* bus = BaseIUMgr::GetBus(inPars->GetPort()); if (bus != 0) { BaseIUVirtBoard* board = bus->GetBoard(inPars->GetAddress()); if (board != 0) { BaseIUVirtPar* par = board->GetParameter(inPars->GetParType(), inPars->GetParName()); if (par != 0) { pai->val = par->GetDouble(); pai->udf = 0; recGblSetSevr( pai, par->GetStatus(), par->GetSeverity() ); return 2; } else { string errorString = "devAiBaseIU (basesAiRead): unknown parameter " + inPars->GetParName() + " of type " + inPars->GetParType(); RecordError recError(reinterpret_cast(pai), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } else { string errorString = "devAiBaseIU (basesAiRead): unknown address"; RecordError recError(reinterpret_cast(pai), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } else { string errorString = "devAiBaseIU (basesAiRead): unknown bus"; RecordError recError(reinterpret_cast(pai), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } // ao record static long basesAoInit(struct aoRecord *pao) { //! scan field must be set to Passive if (pao->scan != menuScanPassive) { string errString = "devAoBaseIU(): ao record must be Passive SCAN"; RecordError recError(reinterpret_cast(pao), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } pao->dpvt = NULL; BaseIUInput* inPars = 0; try { inPars = new BaseIUInput(string(pao->out.value.instio.string)); //! Bus number cannot be negative if (inPars->GetPort() == "") { stringstream errStream; errStream << "devAaBaseIU (basesAoInit): bad port name " << inPars->GetPort(); RecordError recError(reinterpret_cast(pao), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } //! Address must be a positive integer if (inPars->GetAddress() <= 0) { stringstream errStream; errStream << "devAoBaseIU (basesAoInit): bad board address " << inPars->GetAddress(); RecordError recError(reinterpret_cast(pao), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } //! We use ao records for ADC type parameters only if (inPars->GetParType() != string("ADC")) { stringstream errStream; errStream << "devAoBaseIU (basesAoInit): bad parameter type " << inPars->GetParType(); RecordError recError(reinterpret_cast(pao), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } //! If we reached this point then this is an ADC analog output parameter //! Only Cathode Voltage parameter has analog output if (inPars->GetParName() != string("SET")) { stringstream errStream; errStream << "devAoBaseIU (basesAoInit): bad parameter name " << inPars->GetParName(); RecordError recError(reinterpret_cast(pao), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } //! save the address of the input object pao->dpvt = static_cast(inPars); //! We need to read back the parameter from hardware on initialization // BaseIUBus* bus = BaseIUMgr::bmgBusMap[inPars->GetPort()].second; BaseIUVirtBus* bus = BaseIUMgr::GetBus(inPars->GetPort()); if (bus != 0) { BaseIUVirtBoard* board = bus->GetBoard(inPars->GetAddress()); if (board != 0) { BaseIUVirtPar* par = board->GetParameter(inPars->GetParType(), inPars->GetParName()); if (par != 0) { //! read the existing value for the parameter pao->val = par->GetDouble(); pao->udf = false; recGblSetSevr( pao, par->GetStatus(), par->GetSeverity() ); return 2; } else { string errorString = "devAiBaseIU (basesAoInit): unknown parameter"; RecordError recError( reinterpret_cast(pao), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } else { string errorString = "devAiBaseIU (basesAoInit): unknown address"; RecordError recError(reinterpret_cast(pao), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } else { string errorString = "devAiBaseIU (basesAoInit): unknown bus"; RecordError recError(reinterpret_cast(pao), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } //! If there was a thrown exception set disable alarm status with invalid severity //! and disable the record catch (BaseIUInput::BadString & excpt) { string errString = string("devAoBaseIU (basesAoInit): ") + excpt.GetMessage(); RecordError recError(reinterpret_cast(pao), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } pao->udf = true; return statOK; } static long basesAoWrite(struct aoRecord *pao) { //! Find the pointer of the input object BaseIUInput* inPars = 0; if (pao->dpvt == NULL) { string errString = "devAoBaseIU (basesAoWrite) : driver error"; RecordError recError(reinterpret_cast(pao), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } else inPars = static_cast(pao->dpvt); // BaseIUBus* bus = BaseIUMgr::bmgBusMap[inPars->GetPort()].second; BaseIUVirtBus* bus = BaseIUMgr::GetBus(inPars->GetPort()); if (bus != 0) { BaseIUVirtBoard* board = bus->GetBoard(inPars->GetAddress()); if (board != 0) { BaseIUVirtPar* par = board->GetParameter(inPars->GetParType(), inPars->GetParName()); if (par != 0) { par->SetDouble(pao->val); pao->udf = 0; recGblSetSevr( pao, par->GetStatus(), par->GetSeverity() ); return 0; } else { string errorString = "devAoBaseIU (basesAoWrite): unknown parameter"; RecordError recError(reinterpret_cast(pao), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } else { string errorString = "devAoBaseIU (basesAoWrite): unknown address"; RecordError recError(reinterpret_cast(pao), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } else { string errorString = "devAoBaseIU (basesAoWrite): unknown bus"; RecordError recError(reinterpret_cast(pao), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } // bi record static long basesBiInit(struct biRecord* pbi) { pbi->dpvt = NULL; try { BaseIUInput* inPars = new BaseIUInput(string(pbi->inp.value.instio.string)); //! We use bi records for STATUS and DIGITAL type parameters only if (inPars->GetParType() != "STATUS" && inPars->GetParType() != "DIGITAL" ) { stringstream errStream; errStream << "devBiBaseIU (basesBiInit): bad parameter type " << inPars->GetParType(); RecordError recError(reinterpret_cast(pbi), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } if (inPars->GetPort() == "") { stringstream errStream; errStream << "devBiBaseIU (basesBiInit): bad port Name " << inPars->GetPort(); RecordError recError(reinterpret_cast(pbi), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } if (inPars->GetParType() == "STATUS" && inPars->GetAddress() < 0) { stringstream errStream; errStream << "devBiBaseIU (basesBiInit): bad board address " << inPars->GetAddress(); RecordError recError(reinterpret_cast(pbi), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } //! save the address of the input object pbi->dpvt = static_cast(inPars); } //! If there was a thrown exception set disable alarm status with invalid severity //! and disable the record catch (BaseIUInput::BadString & excpt) { string errString = string("devBiBaseIU (basesBiInit): ") + excpt.GetMessage(); RecordError recError(reinterpret_cast(pbi), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } pbi->udf = false; return statOK; } static long basesBiRead(struct biRecord* pbi) { //! Find the pointer of the input object BaseIUInput* inPars = 0; if (pbi->dpvt == NULL) { string errString = "devBiBaseIU (basesBiRead) : driver error"; RecordError recError(reinterpret_cast(pbi), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } else inPars = static_cast(pbi->dpvt); BaseIUVirtBus* bus = BaseIUMgr::GetBus(inPars->GetPort()); if (bus != 0) { BaseIUVirtPar* par = 0; string bitName = ""; if (inPars->GetParType() == "DIGITAL") { // For DIGITAL type parameters the source is the bus itself par = bus->GetParameter( inPars->GetParType(), inPars->GetParType() ); // The bitName will be something like INPA, INPB, OUTC etc. bitName = inPars->GetBitName() + bus->GetDevice()->GetBusStr(); } else if (inPars->GetParType() == "STATUS") { if (inPars->GetAddress() != 0) { // For STATUS type parameters and non-zero address the source is the board in the bus BaseIUVirtBoard* board = bus->GetBoard(inPars->GetAddress()); if (board != 0) { par = board->GetParameter(inPars->GetParType(), inPars->GetParType()); bitName = inPars->GetBitName(); } else { string errorString = "devBiBaseIU (basesBiRead): unknown address"; RecordError recError( reinterpret_cast(pbi), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } else if (inPars->GetAddress() == 0) { // For STATUS type parameters and zero address the source is the bus par = bus->GetParameter(inPars->GetParType(),inPars->GetParType()); bitName = inPars->GetBitName(); } } if (par != 0) { // cout << "devBaseIU : The parameter type is " << inPars->GetParType() << " : " << par->GetName() << // " bit is " << inPars->GetBitName() << endl; // cout << "devBaseIU : Reading from parameter object at " << hex << showbase << par << endl; pbi->rval = static_cast( par->GetBit( bitName ) ); pbi->udf = 0; recGblSetSevr( pbi, par->GetStatus(), par->GetSeverity() ); return 0; } else { string errorString = "devBiBaseIU (basesBiRead): unknown parameter"; RecordError recError(reinterpret_cast(pbi), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } else { string errorString = "devBiBaseIU (basesBiRead): unknown bus"; RecordError recError(reinterpret_cast(pbi), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } // bo record static long basesBoInit(struct boRecord* pbo) { //! scan field must be set to Passive if (pbo->scan != menuScanPassive) { string errString = "devBoBaseIU (basesBoInit): bo record must be Passive SCAN"; RecordError recError(reinterpret_cast(pbo), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } pbo->dpvt = NULL; try { BaseIUInput* inPars = new BaseIUInput( string(pbo->out.value.instio.string)); //! We use bo records for STATUS type parameters only if (inPars->GetParType() != "STATUS" && inPars->GetParType() != "DIGITAL") { stringstream errStream; errStream << "devBoBaseIU (basesBoInit): bad parameter type " << inPars->GetParType(); RecordError recError(reinterpret_cast(pbo), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } if (inPars->GetPort() == "") { stringstream errStream; errStream << "devBoBaseIU (basesBoInit): bad port name " << inPars->GetPort(); RecordError recError(reinterpret_cast(pbo), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } if (inPars->GetAddress() < 0 && inPars->GetParType() == "STATUS") { stringstream errStream; errStream << "devBoBaseIU (basesBoInit): bad board address " << inPars->GetAddress(); RecordError recError(reinterpret_cast(pbo), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } //! save the address of the input object pbo->dpvt = static_cast(inPars); //! Read back the current settings from the hardware // BaseIUBus* bus = BaseIUMgr::bmgBusMap[inPars->GetPort()].second; BaseIUVirtBus* bus = BaseIUMgr::GetBus(inPars->GetPort()); BaseIUVirtPar* par = 0; string bitName = ""; if (inPars->GetParType() == "DIGITAL") { // For DIGITAL type parameters the source is the bus itself par = bus->GetParameter(inPars->GetParType(), inPars->GetParType()); // The bitName will be something like INPA, INPB, OUTC etc. bitName = inPars->GetBitName() + bus->GetDevice()->GetBusStr(); } else if (inPars->GetParType() == "STATUS") { if (bus != 0) { if (inPars->GetAddress() != 0) { BaseIUVirtBoard* board = bus->GetBoard(inPars->GetAddress()); if (board != 0) { par = board->GetParameter(inPars->GetParType(), inPars->GetParType()); bitName = inPars->GetBitName(); } else { string errorString = "devBoBaseIU (basesBoInit): unknown parameter"; RecordError recError( reinterpret_cast(pbo), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } else if (inPars->GetAddress() == 0) { // For STATUS type parameters and zero address the source is the bus par = bus->GetParameter(inPars->GetParType(),inPars->GetParType()); bitName = inPars->GetBitName(); } } if (par != 0) { pbo->rval = static_cast( par->GetBit( inPars->GetBitName() ) ); pbo->udf = 0; recGblSetSevr( pbo, par->GetStatus(), par->GetSeverity() ); return 0; } else { string errorString = "devBoBaseIU (basesBoInit): unknown address"; RecordError recError(reinterpret_cast(pbo), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } else { string errorString = "devBoBaseIU (basesBoInit): unknown bus"; RecordError recError(reinterpret_cast(pbo), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } //! If there was a thrown exception set disable alarm status with invalid severity //! and disable the record catch (BaseIUInput::BadString & excpt) { string errString = string("devBoBaseIU (basesBoInit): ") + excpt.GetMessage(); RecordError recError(reinterpret_cast(pbo), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } pbo->udf = false; return statOK; } static long basesBoWrite(struct boRecord *pbo) { // int retStatus = 0; //! Find the pointer of the input object BaseIUInput* inPars = 0; if (pbo->dpvt == NULL) { string errString = "devBoBaseIU (basesBoWrite) : driver error"; RecordError recError(reinterpret_cast(pbo), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } else inPars = static_cast(pbo->dpvt); BaseIUVirtBus* bus = BaseIUMgr::GetBus(inPars->GetPort()); if (bus != 0) { BaseIUVirtBoard* board = 0; BaseIUVirtPar* par = 0; string bitName = ""; if (inPars->GetParType() == "DIGITAL") { // For DIGITAL type parameters the source is the bus itself par = bus->GetParameter(inPars->GetParType(), inPars->GetParType()); // The bitName will be something like INPA, INPB, OUTC etc. bitName = inPars->GetBitName() + bus->GetDevice()->GetBusStr(); } else if (inPars->GetParType() == "STATUS") { if (inPars->GetAddress() != 0) { board = bus->GetBoard(inPars->GetAddress()); if (board != 0) { par = board->GetParameter(inPars->GetParType(), inPars->GetParType()); bitName = inPars->GetBitName(); } else { string errorString = "devBoBaseIU (basesBoWrite): unknown address"; RecordError recError( reinterpret_cast(pbo), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } else if (inPars->GetAddress() == 0) { // For STATUS type parameters and zero address the source is the bus par = bus->GetParameter(inPars->GetParType(),inPars->GetParType()); bitName = inPars->GetBitName(); } } if (par != 0) { bool setVal = (pbo->rval != 0); // If address is not 0, that is it is a parameter for a real bus // set the but to the value. if (inPars->GetAddress() > 0) { par->SetBit(setVal, bitName); pbo->udf = 0; recGblSetSevr( pbo, par->GetStatus(), par->GetSeverity() ); } // If address is zero set the parameter for the whole bus by setting up // a high priority call in the Sync procedure of the bus. if (inPars->GetAddress() == 0) { // Set the write values of the bitName bit for all parameters on // on this bus of the same type to this values. // This is done to prevent the individual parameters fighting // the value set by address 0 parameter. // cout << "Set value is " << setVal << endl; bus->SetParameter(inPars->GetParType(), bitName, &setVal); // Now set the bit which really sets up a call to be processed in // middle of the Sync method of the bus. // Bind SetBit function for the parameter to calFunc; BaseIUVirtBus::PriorityFuncType callFunc; cout << "Binding SetBit for parameter <" << par->GetName() << "> bit <" << bitName << "> with value " << setVal << endl; callFunc = boost::bind(static_cast(&BaseIUVirtPar::SetBit), par, setVal, bitName ); cout << "Placing priority function into queue" << endl; bus->AddPrioritySyncCall( callFunc ); if( par->GetStatus() != NO_ALARM || par->GetSeverity() != NO_ALARM ) { recGblSetSevr( pbo, par->GetStatus(), par->GetSeverity() ); } // retStatus = par->SetBit(setVal, bitName); pbo->udf = 0; } return 0; } else { string errorString = "devBoBaseIU (basesBoWrite): unknown parameter"; RecordError recError(reinterpret_cast(pbo), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } else { string errorString = "devBoBaseIU (basesBoWrite): unknown bus"; RecordError recError(reinterpret_cast(pbo), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } static long basesMbbiDirectInit(struct mbbiDirectRecord *pmdi) { pmdi->dpvt = NULL; try { BaseIUInput* inPars = new BaseIUInput( string(pmdi->inp.value.instio.string)); //! We use mbbiDirect records for ADC type parameters only. //! These are for the status parameters that are in firmware presented as ADC values //! In the driver they are represented by BaseIUParADC class. Other normal status //! are represented by binary records. if (inPars->GetParType() != "ADC") { stringstream errStream; errStream << "devMbbiDirectBaseIU (basesMbbiDirectInit): bad parameter type " << inPars->GetParType(); RecordError recError(reinterpret_cast(pmdi), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } if (inPars->GetPort() == "") { stringstream errStream; errStream << "devMbbiDirectBaseIU (basesMbbiDirectInit): bad port Name " << inPars->GetPort(); RecordError recError(reinterpret_cast(pmdi), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } if (inPars->GetAddress() <= 0) { stringstream errStream; errStream << "devMbbiDirectBaseIU (basesMbbiDirectInit): bad board address " << inPars->GetAddress(); RecordError recError(reinterpret_cast(pmdi), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } //! save the address of the input object pmdi->dpvt = static_cast(inPars); } //! If there was a thrown exception set disable alarm status with invalid severity //! and disable the record catch (BaseIUInput::BadString & excpt) { string errString = string("devMbbiDirectBaseIU (basesMbbiDirectInit): ") + excpt.GetMessage(); RecordError recError(reinterpret_cast(pmdi), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } pmdi->udf = false; return statOK; } //-------------------------------------------------------------------- static long basesMbbiDirectRead(struct mbbiDirectRecord *pmdi) { //! Find the pointer of the input object BaseIUInput* inPars = 0; if (pmdi->dpvt == NULL) { string errString = "devMbbiDirectBaseIU (basesMbbiDirectRead) : driver error"; RecordError recError(reinterpret_cast(pmdi), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } else inPars = static_cast(pmdi->dpvt); BaseIUVirtBus* bus = BaseIUMgr::GetBus(inPars->GetPort()); if (bus != 0) { BaseIUVirtBoard* board = bus->GetBoard(inPars->GetAddress()); if (board != 0) { BaseIUVirtPar* par = board->GetParameter(inPars->GetParType(), inPars->GetParName()); if (par != 0) { // "ADC" type parameters in BaseIUParADC have real values. // Since the statuses for the power chassis is kept as an ADC in the firmware they are implemented // as an ADC in this driver. But here we must round it up to the integer value. pmdi->val = round(par->GetDouble()); pmdi->udf = 0; recGblSetSevr( pmdi, par->GetStatus(), par->GetSeverity() ); return 2; } else { string errorString = "devMbbiDirectBaseIU (basesMbbiDirectRead): unknown parameter " + inPars->GetParName() + " of type " + inPars->GetParType(); RecordError recError(reinterpret_cast(pmdi), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } else { string errorString = "devMbbiDirectBaseIU (basesMbbiDirectRead): unknown address"; RecordError recError(reinterpret_cast(pmdi), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } else { string errorString = "devMbbiDirectBaseIU (basesMbbiDirectRead): unknown bus"; RecordError recError(reinterpret_cast(pmdi), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } //-------------------------------------------------------------------- static long basesLiInit(struct longinRecord *pli) { pli->dpvt = NULL; try { BaseIUInput* inPars = new BaseIUInput( string(pli->inp.value.instio.string)); //! We use longin records for ANAGATE type parameters only. //! These are for the ANAGATE parameters to match the scheme for GlueX HV . if (inPars->GetParType() != "ANAGATE") { stringstream errStream; errStream << "devLiBaseIU (basesLIInit): bad parameter type " << inPars->GetParType(); RecordError recError(reinterpret_cast(pli), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } if (inPars->GetPort() == "") { stringstream errStream; errStream << "devLiBaseIU (basesLiInit): bad port Name " << inPars->GetPort(); RecordError recError(reinterpret_cast(pli), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } //! save the address of the input object pli->dpvt = static_cast(inPars); } //! If there was a thrown exception set disable alarm status with invalid severity //! and disable the record catch (BaseIUInput::BadString & excpt) { string errString = string("devLiBaseIU (basesLiInit): ") + excpt.GetMessage(); RecordError recError(reinterpret_cast(pli), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } pli->udf = false; return statOK; } //-------------------------------------------------------------------- static long basesLiRead(struct longinRecord *pli) { //! Find the pointer of the input object BaseIUInput* inPars = 0; if (pli->dpvt == NULL) { string errString = "devLiBaseIU (basesLiRead) : driver error"; RecordError recError(reinterpret_cast(pli), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } else inPars = static_cast(pli->dpvt); BaseIUVirtBus* bus = BaseIUMgr::GetBus(inPars->GetPort()); if (bus != 0) { if (inPars->GetParType() == "ANAGATE") { if (inPars->GetParName() == "NBASES") { pli->val = bus->GetNumberOfRealBoards(); pli->udf = 0; return 2; } else { string errorString = "devLiBaseIU (basesLiRead): unknown parameter " + inPars->GetParName() + " of type " + inPars->GetParType(); RecordError recError(reinterpret_cast(pli), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } } else { string errorString = "devLiBaseIU (basesLiRead): unknown bus"; RecordError recError(reinterpret_cast(pli), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } return 0; } //-------------------------------------------------------------------- static long basesSiInit(struct stringinRecord *psi) { psi->dpvt = NULL; try { BaseIUInput* inPars = new BaseIUInput(string(psi->inp.value.instio.string)); //! We use stringin records for ANAGATE type parameters only. //! These are for the ANAGATE parameters to match the scheme for GlueX HV . if (inPars->GetParType() != "ANAGATE") { stringstream errStream; errStream << "devSiBaseIU (basesSiRead): bad parameter type " << inPars->GetParType(); RecordError recError(reinterpret_cast(psi), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } if (inPars->GetPort() == "") { stringstream errStream; errStream << "devSiBaseIU (basesSiInit): bad port Name " << inPars->GetPort(); RecordError recError(reinterpret_cast(psi), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errStream.str()); recError.Disable(); return S_db_badField; } //! save the address of the input object psi->dpvt = static_cast(inPars); } //! If there was a thrown exception set disable alarm status with invalid severity //! and disable the record catch (BaseIUInput::BadString & excpt) { string errString = string("devSiBaseIU (basesLiInit): ") + excpt.GetMessage(); RecordError recError(reinterpret_cast(psi), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } psi->udf = false; return statOK; } //-------------------------------------------------------------------- static long basesSiRead(struct stringinRecord *psi) { //! Find the pointer of the input object BaseIUInput* inPars = 0; if (psi->dpvt == NULL) { string errString = "devSiBaseIU (basesSiRead) : driver error"; RecordError recError(reinterpret_cast(psi), S_db_badField, DISABLE_ALARM, INVALID_ALARM, errString); recError.Disable(); return S_db_badField; } else inPars = static_cast(psi->dpvt); BaseIUVirtBus* bus = BaseIUMgr::GetBus(inPars->GetPort()); if (bus != 0) { if (inPars->GetParType() == "ANAGATE") { if (inPars->GetParName() == "IP") { strcpy( psi->val, bus->GetDevice()->GetIP().c_str() ); psi->udf = 0; return 2; } else { string errorString = "devSiBaseIU (basesSiRead): unknown parameter " + inPars->GetParName() + " of type " + inPars->GetParType(); RecordError recError(reinterpret_cast(psi), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } } } else { string errorString = "devSiBaseIU (basesSiRead): unknown bus"; RecordError recError(reinterpret_cast(psi), S_db_badField, READ_ALARM, INVALID_ALARM, errorString); return S_db_badField; } return 0; } //-------------------------------------------------------------------- // // // static long basesLoInit(struct longoutRecord *plo) // { // // lo.scan must be Passive // if (plo->scan != menuScanPassive) { // recGblRecordError(S_db_badField,(void *)plo, // "devSnmpLo (init_record) SCAN must be Passive"); // return(S_db_badField); // } // // // lo.out must be an INST_IO // switch (plo->out.type) { // case INST_IO: // break; // // default : // recGblRecordError(S_db_badField,(void *)plo, // "devSnmpLo (init_record) Illegal OUT field"); // return(S_db_badField); // } // // checkInit(); // devSnmp_device *pDevice = pManager->createDevice((struct dbCommon *) plo, &plo->out, (char *) "longout"); // if (! pDevice) { // recGblRecordError(S_db_badField, // (void *)plo,"devSnmpLo (init_record) bad parameters"); // return(S_db_badField); // } // pDevice->setPollGapMSec(devSnmp_device::PassivePollGapMSec); // // /* request a periodic call to basesLoReadback, so our display value is // periodically updated with value from the remote host */ // pDevice->setPeriodicCallback(basesLoReadback,(devSnmp_device::PassivePollGapMSec / 1000.0)); // // plo->udf = FALSE; // return(epicsOk); // } // //-------------------------------------------------------------------- // static long basesLoWrite(struct longoutRecord *plo) // { // devSnmp_device *pDevice; // // if (plo->dpvt == NULL) // return(epicsError); // else // pDevice = (devSnmp_device *) plo->dpvt; // // /* if we're being called as a result of a readback update, // just report success */ // if (pDevice->doingProcess()) return(epicsOk); // // // fill in set data // long status = epicsOk; // char tmp[40]; // sprintf(tmp,"%ld", (long) plo->val); // pDevice->set(tmp); // // return(status); // } //! Constructor of the class to handle record-related errors. //! Arguments are the pointer to the record, the error condition, //! alarm status to be set, alarm severity to be set, and error //! string that will need to be printout out. //! This constructor will create the object, set the alarm status and //! the severity and print error message. //! It will not disable the record, there is a separate method for //! disabling record on error. RecordError::RecordError(struct dbCommon* prec, const long epicsError, const long epicsAlarm, const long epicsSevr, const string errString) : recPtr(prec) { if (recPtr != 0) { if (recGblSetSevr( recPtr, epicsAlarm, epicsSevr ) && (recPtr->stat != epicsAlarm || recPtr->sevr != epicsSevr)) { recGblRecordError(epicsError, static_cast(recPtr), errString.c_str()); } } return; } //! Method to disable record with appropriate error message and alarm status void RecordError::Disable() { recPtr->disa = true; recPtr->disv = true; /* Record disabled when DISA = DISV */ recPtr->disp = true; /* Also disable putFields to this record*/ return; }