00001 #ifndef CONFIGURATION_UTILITY_H
00002 #define CONFIGURATION_UTILITY_H
00003
00004 #include <Sct/AbcdModule.h>
00005 #include <Sct/AbcdScans.h>
00006 #include <Sct/AbcdChip.h>
00007 #include "extraScans.h"
00008 #include "SctApiFwd.h"
00009
00010 #include <iostream>
00011 #include <sstream>
00012
00013 namespace SctApi{
00015 class ConfigUtility{
00016 public:
00021 static unsigned diff(const ABCDBasic& first, const ABCDBasic& second, bool print=false);
00026 static unsigned diff(const ABCDConfig& first, const ABCDConfig& second, bool print=false);
00031 static unsigned diff(const ABCDCaldata& first, const ABCDCaldata& second, bool print=false);
00036 static unsigned diff(const ABCDChip& first, const ABCDChip& second, bool print=false);
00041 static unsigned diff(const ABCDModule& first, const ABCDModule& second, bool print=false);
00046 static unsigned diffSN(const ABCDModule& first, const ABCDModule& second, bool print=false);
00050 static std::auto_ptr<ABCDModule> clone(const ABCDModule& first);
00054 static std::auto_ptr<ABCDBasic> clone(const ABCDBasic& first);
00055
00059 static void modifyVar(ABCDModule* module, UINT32 typ, FLOAT32 val);
00063 static void modifyVar(ABCDModule* module, unsigned chip, UINT32 typ, FLOAT32 val);
00064
00068 static bool isBocRegister(UINT32 typ);
00069
00073 static bool isModuleRegister(UINT32 typ);
00074
00078 static bool isTimRegister(UINT32 typ);
00079
00080 enum ConfigVarType {
00081 BOC_CHANNEL_CONFIG_VAR, BOC_GLOBAL_CONFIG_VAR,
00082 MODULE_GLOBAL_CONFIG_VAR, MODULE_CHIP_CONFIG_VAR, MODULE_CHANNEL_CONFIG_VAR,
00083 TIM_CONFIG_VAR, TRIGGER_VAR, UNKNOWN_CONFIG_VAR
00084 };
00085
00086 static std::string apiBitFieldToString(unsigned bitfield);
00087
00091 static ConfigVarType variableType(UINT32 typ);
00092 private:
00093 static ConfigUtility& ConfigUtility::instance();
00094 ConfigUtility();
00095 UINT16 config_compare_mask;
00096 static void setToken(ABCDModule* module, unsigned token, int link0, int link1);
00097 static INT32 ConfigUtility::setChipRole(ABCDModule *module, UINT32 theChip, ABCD_ROLES role);
00098 };
00099
00100 inline std::auto_ptr<ABCDModule> ConfigUtility::clone(const ABCDModule& first){
00101 std::auto_ptr<ABCDModule> m (new ABCDModule);
00102 const size_t size=sizeof(ABCDModule);
00103 memcpy(m.get(), &first, size);
00104 return m;
00105 }
00106
00107 inline std::auto_ptr<ABCDBasic> ConfigUtility::clone(const ABCDBasic& first){
00108 std::auto_ptr<ABCDBasic> a (new ABCDBasic);
00109 const size_t size=sizeof(ABCDBasic);
00110 memcpy(a.get(), &first, size);
00111 return a;
00112 }
00113
00114 inline
00115 ConfigUtility::ConfigUtility(){
00116 config_compare_mask=0xffffffff;
00117 reinterpret_cast<ABCDConfig*>(&config_compare_mask)->padding=0;
00118 }
00119
00120 inline
00121 ConfigUtility& ConfigUtility::instance(){
00122 static ConfigUtility config;
00123 return config;
00124 }
00125
00126
00127 inline unsigned ConfigUtility::diff(const ABCDConfig& first, const ABCDConfig& second, bool print){
00128 unsigned diff_bits=SCTAPI_CONFIG_NONE;
00129 const UINT32* p=reinterpret_cast<const UINT32*>(&first);
00130 const UINT32* q=reinterpret_cast<const UINT32*>(&second);
00131 const UINT32& cfg_mask=instance().config_compare_mask;
00132
00133 UINT32 cfgdiff = *p^*q;
00134 cfgdiff &= cfg_mask;
00135 if (cfgdiff) {
00136 diff_bits |= 1<<SCTAPI_CONFIG_CFG;
00137 }
00138 if (print && diff_bits) std::cout << "CFG: first = 0x" << std::hex << *p << " second = 0x" << *q << std::dec << std::endl;
00139 return diff_bits;
00140 }
00141
00142 inline unsigned ConfigUtility::diff(const ABCDBasic& first, const ABCDBasic& second, bool print){
00143 unsigned diff_bits=0;
00144
00145 if (first.vthr!=second.vthr || first.vcal!=second.vcal ||
00146 first.delay!=second.delay || first.preamp!=second.preamp ||
00147 first.shaper!=second.shaper) diff_bits|=1<<SCTAPI_CONFIG_BASIC;
00148
00149 for (unsigned i=0; i<4; ++i){
00150 if (first.mask[i]!=second.mask[i]) diff_bits|=1<<SCTAPI_CONFIG_MASK;
00151 }
00152 if (print){
00153 if (first.vthr!=second.vthr) std::cout << "vthr first = " << +first.vthr << " second = " << +second.vthr << std::endl;
00154 if (first.vcal!=second.vcal) std::cout << "vcal first = " << +first.vcal << " second = " << +second.vcal << std::endl;
00155 if (first.delay!=second.delay) std::cout << "delay first = " << +first.delay << " second = " << +second.delay << std::endl;
00156 if (first.preamp!=second.preamp) std::cout << "preamp first = " << +first.preamp << " second = " << +second.preamp << std::endl;
00157 if (first.shaper!=second.shaper) std::cout << "shaper first = " << +first.shaper << " second = " << +second.shaper << std::endl;
00158 for (unsigned i=0; i<4; ++i){
00159 if (first.mask[i]!=second.mask[i]){
00160 std::cout << "mask[" << i<<"] first = 0x" << std::hex << +first.mask[i]
00161 << " second = 0x" << +second.mask[i] << std::dec << std::endl;
00162 }
00163 }
00164 }
00165 diff_bits |= diff(first.config, second.config, print);
00166 return diff_bits;
00167 }
00168
00169 inline unsigned ConfigUtility::diff(const ABCDCaldata& first, const ABCDCaldata& second, bool print){
00170 unsigned diff_bits=SCTAPI_CONFIG_NONE;
00171
00172 if (first.rc_function!=second.rc_function ||
00173 first.c_factor!=second.c_factor) diff_bits |= 1<<SCTAPI_CONFIG_OTHER;
00174
00175 for (unsigned i=0; i<3; ++i){
00176 if (first.rc_params[i]!=second.rc_params[i]) diff_bits |= 1<< SCTAPI_CONFIG_OTHER;
00177 }
00178
00179 if (print){
00180 if (first.rc_function!=second.rc_function) {
00181 std::cout << "rc_function first = " << +first.rc_function << " second = " << +second.rc_function << std::endl;
00182 }
00183 if (first.c_factor!=second.c_factor) {
00184 std::cout << "c_factor first = " << first.c_factor << " second = " << second.c_factor << std::endl;
00185 }
00186 for (unsigned i=0; i<3; ++i){
00187 if (first.rc_params[i]!=second.rc_params[i]){
00188 std::cout << "rc_params[" << i << "] first = " << first.rc_params[i]
00189 << " second = " << second.rc_params[i] << std::endl;
00190 }
00191 }
00192 }
00193 return diff_bits;
00194 }
00195
00196 inline unsigned ConfigUtility::diff(const ABCDChip& first, const ABCDChip& second, bool print){
00197 unsigned diff_bits=SCTAPI_CONFIG_NONE;
00198
00199 for (unsigned i=0; i<N_SCT_CHANS; ++i){
00200 if (first.trim[i]!=second.trim[i]) {
00201 diff_bits |= 1<<SCTAPI_CONFIG_TRIM;
00202 }
00203 }
00204 if (diff_bits && print){
00205 unsigned start, stop;
00206 for (unsigned iset=0; iset<4; ++iset){
00207 start=iset*32;
00208 stop=(iset+1)*32-1;
00209 std::cout << "trim ["<<start<<"->"<<stop<<"] first = 0x" << std::hex;
00210 for (unsigned ii=start; ii<stop; ++ii){
00211 std::cout << +first.trim[ii];
00212 }
00213 std::cout << " second = 0x";
00214 for (unsigned ii=start; ii<stop; ++ii){
00215 std::cout << +second.trim[ii];
00216 }
00217 std::cout << std::dec << std::endl;
00218 }
00219 }
00220
00221 if (first.active!=second.active ||
00222 first.address!=second.address ||
00223 first.target!=second.target ) diff_bits |= 1<<SCTAPI_CONFIG_OTHER;
00224
00225 if (print){
00226 if (first.active!=second.active) std::cout << "active first = " << +first.active << " second = " << +second.active << std::endl;
00227 if (first.address!=second.address) std::cout << "address first = " << +first.address << " second = " << +second.address << std::endl;
00228 if (first.target!=second.target) std::cout << "target first = " << +first.target << " second = " << +second.target << std::endl;
00229 }
00230
00231 diff_bits |= diff(first.basic, second.basic, print);
00232 diff_bits |= diff(first.caldata, second.caldata, print);
00233
00234 return diff_bits;
00235 }
00236
00237 inline unsigned ConfigUtility::diff(const ABCDModule& first, const ABCDModule& second, bool print){
00238 unsigned diff_bits=SCTAPI_CONFIG_NONE;
00239
00240 for (unsigned ichip=0; ichip<N_SCT_CHIPS; ++ichip){
00241 if (print) std::cout << "chip " << ichip << std::endl;
00242 diff_bits |= diff(first.chip[ichip], second.chip[ichip], print);
00243 }
00244
00245 if (first.active!=second.active ||
00246 first.select!=second.select || first.groupId!=second.groupId ||
00247 first.pTTC!=second.pTTC || first.rTTC!=second.rTTC ||
00248 first.rx[0]!=second.rx[0] || first.rx[1]!=second.rx[1] ||
00249 first.mid != second.mid
00250 ){
00251 diff_bits |= 1<<SCTAPI_CONFIG_OTHER;
00252 }
00253 if (print){
00254 if (first.active!=second.active) std::cout << "active first = " << +first.active << " second = " << +second.active << std::endl;
00255 if (first.select!=second.select) std::cout << "select first = " << +first.select << " second = " << +second.select << std::endl;
00256 if (first.pTTC!=second.pTTC) std::cout << "pTTC first = " << +first.pTTC << " second = " << +second.pTTC << std::endl;
00257 if (first.rx[0]!=second.rx[0]) std::cout << "rx[0] first = " << +first.rx[0] << " second = " << +second.rx[0] << std::endl;
00258 if (first.rx[1]!=second.rx[1]) std::cout << "rx[1] first = " << +first.rx[1] << " second = " << +second.rx[1] << std::endl;
00259 if (first.mid!=second.mid) std::cout << "mid first = " << +first.mid << " second = " << +second.mid << std::endl;
00260 }
00261
00262 diff_bits |= diffSN(first, second);
00263 return diff_bits;
00264 }
00265
00266 inline unsigned ConfigUtility::diffSN(const ABCDModule& first, const ABCDModule& second, bool print){
00267 unsigned diff_bits=0;
00268 for (unsigned i=0; i<16; ++i){
00269 if (first.serialNumber[i] != second.serialNumber[i]) diff_bits&= 1<<SCTAPI_CONFIG_OTHER;
00270 }
00271 if (diff_bits && print ){
00272 std::cout << "s/n first = " << first.serialNumber << " second = " << second.serialNumber << std::endl;
00273 }
00274 return diff_bits;
00275 }
00276
00277 inline std::string ConfigUtility::apiBitFieldToString(unsigned bitfield){
00278 std::ostringstream oss;
00279 if (bitfield & 1 << SCTAPI_CONFIG_CFG) oss << "Cfg";
00280 if (bitfield & 1 << SCTAPI_CONFIG_BASIC) oss << "Basic";
00281 if (bitfield & 1 << SCTAPI_CONFIG_TRIM) oss << "Trim";
00282 if (bitfield & 1 << SCTAPI_CONFIG_MASK) oss << "Mask";
00283 if (bitfield & 1 << SCTAPI_CONFIG_OTHER) oss << "Other";
00284 if (bitfield & 1 << SCTAPI_CONFIG_ALL) oss << "All";
00285 return oss.str();
00286 }
00287
00288 inline bool ConfigUtility::isBocRegister(UINT32 typ){
00289 if (variableType(typ)==BOC_CHANNEL_CONFIG_VAR ||
00290 variableType(typ)==BOC_GLOBAL_CONFIG_VAR){
00291 return true;
00292 }
00293 return false;
00294 }
00295
00296 inline bool ConfigUtility::isTimRegister(UINT32 typ){
00297 if (variableType(typ)==TIM_CONFIG_VAR ){
00298 return true;
00299 }
00300 return false;
00301 }
00302
00303 inline bool ConfigUtility::isModuleRegister(UINT32 typ){
00304 if (variableType(typ)==MODULE_GLOBAL_CONFIG_VAR ||
00305 variableType(typ)==MODULE_CHIP_CONFIG_VAR ||
00306 variableType(typ)==MODULE_CHANNEL_CONFIG_VAR ) {
00307 return true;
00308 }
00309 return false;
00310 }
00311
00312 }
00313
00314 #endif