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