00001 #ifndef _ots_FEVInterface_h_
00002 #define _ots_FEVInterface_h_
00003
00004 #include "otsdaq-core/FiniteStateMachine/VStateMachine.h"
00005 #include "otsdaq-core/WorkLoopManager/WorkLoop.h"
00006 #include "otsdaq-core/Configurable/Configurable.h"
00007 #include "otsdaq-core/FECore/FESlowControlsWorkLoop.h"
00008
00009
00010
00011 #include "otsdaq-core/FECore/FESlowControlsChannel.h"
00012
00013 #include <string>
00014 #include <iostream>
00015 #include <vector>
00016 #include <array>
00017
00018 #define __ARGS__ FEVInterface::frontEndMacroInArgs_t argsIn, FEVInterface::frontEndMacroOutArgs_t argsOut
00019 #define __GET_ARG_IN__(X,Y) getFEMacroInputArgumentValue<Y> (argsIn ,X)
00020 #define __GET_ARG_OUT__(X) FEVInterface::getFEMacroOutputArgument (argsOut,X)
00021 #define __SET_ARG_OUT__(X,Y) FEVInterface::setFEMacroOutputArgumentValue (argsOut,X,Y)
00022
00023 namespace ots
00024 {
00025
00026 class FrontEndHardwareBase;
00027 class FrontEndFirmwareBase;
00028 class FEInterfaceConfigurationBase;
00029
00030
00031 class FEVInterface : public VStateMachine, public WorkLoop, public Configurable
00032 {
00033 public:
00034
00035 FEVInterface (const std::string& interfaceUID, const ConfigurationTree& theXDAQContextConfigTree, const std::string& configurationPath)
00036 : WorkLoop (interfaceUID)
00037 , Configurable (theXDAQContextConfigTree, configurationPath)
00038 , interfaceUID_ (interfaceUID)
00039 , interfaceType_ (theXDAQContextConfigTree_.getBackNode(theConfigurationPath_).getNode("FEInterfacePluginName").getValue<std::string>())
00040 , daqHardwareType_ ("NOT SET")
00041 , firmwareType_ ("NOT SET")
00042 , slowControlsWorkLoop_ (interfaceUID + "-SlowControls", this)
00043 {}
00044
00045 virtual ~FEVInterface (void) {;}
00046
00048
00049
00050
00051
00052
00053
00054
00055
00056
00058
00059 const std::string& getInterfaceUID (void) const {return interfaceUID_;}
00060 const std::string& getDaqHardwareType (void) const {return daqHardwareType_;}
00061 const std::string& getFirmwareType (void) const {return firmwareType_;}
00062 const std::string& getInterfaceType (void) const {return interfaceType_;}
00063
00064 virtual int universalRead (char* address, char* returnValue) = 0;
00065 virtual void universalWrite (char* address, char* writeValue) = 0;
00066 const unsigned int& getUniversalAddressSize (void) {return universalAddressSize_;}
00067 const unsigned int& getUniversalDataSize (void) {return universalDataSize_;}
00068
00069 FrontEndHardwareBase* getHardwareP (void) const {return theFrontEndHardware_;}
00070 FrontEndFirmwareBase* getFirmwareP (void) const {return theFrontEndFirmware_;}
00071
00072 void runSequenceOfCommands (const std::string &treeLinkName);
00073
00075
00076 void configure (void) { __COUT__ << "\t Configure" << std::endl; runSequenceOfCommands("LinkToConfigureSequence"); }
00077 void start (std::string runNumber) { __COUT__ << "\t Start" << std::endl; runSequenceOfCommands("LinkToStartSequence"); }
00078 void stop (void) { __COUT__ << "\t Stop" << std::endl; runSequenceOfCommands("LinkToStopSequence"); }
00079 void halt (void) { stop();}
00080 void pause (void) { stop();}
00081 void resume (void) { start("");}
00082 bool running (void) { return false;}
00083
00085
00087
00088 void configureSlowControls (void);
00089 bool slowControlsRunning (void);
00090 void startSlowControlsWorkLooop (void) {slowControlsWorkLoop_.startWorkLoop();}
00091 void stopSlowControlsWorkLooop (void) {slowControlsWorkLoop_.stopWorkLoop();}
00092
00094
00095
00097
00098
00099
00100 using frontEndMacroInArg_t = std::pair<const std::string , const std::string >;
00101 using frontEndMacroInArgs_t = const std::vector<frontEndMacroInArg_t> &;
00102 using frontEndMacroOutArg_t = std::pair<const std::string , std::string >;
00103 using frontEndMacroOutArgs_t = std::vector<frontEndMacroOutArg_t> &;
00104 using frontEndMacroFunction_t = void (ots::FEVInterface::* )(frontEndMacroInArgs_t, frontEndMacroOutArgs_t);
00105 struct frontEndMacroStruct_t
00106 {
00107 frontEndMacroStruct_t(const frontEndMacroFunction_t &feMacroFunction,
00108 const std::vector<std::string> &namesOfInputArgs,
00109 const std::vector<std::string> &namesOfOutputArgs,
00110 const uint8_t requiredUserPermissions)
00111 :macroFunction_(feMacroFunction)
00112 ,namesOfInputArguments_(namesOfInputArgs)
00113 ,namesOfOutputArguments_(namesOfOutputArgs)
00114 ,requiredUserPermissions_(requiredUserPermissions)
00115 {}
00116
00117 const frontEndMacroFunction_t macroFunction_;
00118 const std::vector<std::string> namesOfInputArguments_, namesOfOutputArguments_;
00119 const uint8_t requiredUserPermissions_;
00120 };
00121 const std::map<std::string, frontEndMacroStruct_t>& getMapOfFEMacroFunctions() {return mapOfFEMacroFunctions_;}
00122
00124
00125 protected:
00126 bool workLoopThread(toolbox::task::WorkLoop* workLoop){continueWorkLoop_ = running(); return continueWorkLoop_;}
00127 std::string interfaceUID_;
00128 std::string interfaceType_;
00129
00130
00131 std::string daqHardwareType_;
00132 std::string firmwareType_;
00133
00134 FrontEndHardwareBase* theFrontEndHardware_ = nullptr;
00135 FrontEndFirmwareBase* theFrontEndFirmware_ = nullptr;
00136
00137 unsigned int universalAddressSize_ = 0;
00138 unsigned int universalDataSize_ = 0;
00139
00140
00141 std::map<std::string, FESlowControlsChannel> mapOfSlowControlsChannels_;
00142 FESlowControlsWorkLoop slowControlsWorkLoop_;
00143
00144
00145
00146
00147 std::map<std::string, frontEndMacroStruct_t> mapOfFEMacroFunctions_;
00148 void registerFEMacroFunction(const std::string &feMacroName, frontEndMacroFunction_t feMacroFunction, const std::vector<std::string> &namesOfInputArgs, const std::vector<std::string> &namesOfOutputArgs, uint8_t requiredUserPermissions);
00149
00150 public:
00151 static bool isNumber(const std::string& s) ;
00152 static const std::string& getFEMacroInputArgument (frontEndMacroInArgs_t &argsIn, const std::string &argName);
00153 protected:
00154 static std::string& getFEMacroOutputArgument (frontEndMacroOutArgs_t &argsOut, const std::string& argName);
00155
00156
00157 template<class T>
00158 std::string& setFEMacroOutputArgumentValue(
00159 frontEndMacroOutArgs_t &argsOut,
00160 const std::string &argName, const T& value) const
00161 {
00162 std::string& argOut = getFEMacroOutputArgument(argsOut,argName);
00163 std::stringstream ss; ss << value;
00164 argOut = ss.str();
00165 return argOut;
00166 }
00167
00168 };
00169
00170
00171 template<class T>
00172 T getFEMacroInputArgumentValue(
00173 FEVInterface::frontEndMacroInArgs_t &argsIn, const std::string &argName)
00174 {
00175
00176
00177
00178 const std::string& data = FEVInterface::getFEMacroInputArgument(argsIn, argName);
00179
00180
00181 T retValue;
00182
00183 if(!FEVInterface::isNumber(data))
00184 {
00185 __SS__ << "Error extracting value for argument named '" <<
00186 argName << ".' The value '" << data << "' is not a number!" << std::endl;
00187 __COUT__ << "\n" << ss.str();
00188 throw std::runtime_error(ss.str());
00189 }
00190 __COUTV__(data);
00191
00192 if(typeid(double) == typeid(retValue))
00193 retValue = strtod(data.c_str(),0);
00194 else if(typeid(float) == typeid(retValue))
00195 retValue = strtof(data.c_str(),0);
00196 else if(data.size() > 2 && data[1] == 'x')
00197 retValue = strtol(data.c_str(),0,16);
00198 else if(data.size() > 1 && data[0] == 'b')
00199 retValue = strtol(data.substr(1).c_str(),0,2);
00200 else
00201 retValue = strtol(data.c_str(),0,10);
00202
00203 return retValue;
00204 }
00205
00206 template<>
00207 std::string getFEMacroInputArgumentValue<std::string> (FEVInterface::frontEndMacroInArgs_t &argsIn, const std::string &argName);
00208
00209
00210 }
00211
00212 #endif