ICP  1
dae2_card.cpp
Go to the documentation of this file.
1 #include "stdafx.h"
2 
3 #include "isisvme.h"
4 #include "dae2_card.h"
5 
6 template <class DAECardPolicy>
7 DAE2Card<DAECardPolicy>::DAE2Card(int position, ISISVME* vme, DAEstatus& status) : m_position(position), m_vme(vme)
8 {
9  setLoggerName("DAE2CARD");
10 }
11 
12 template <class DAECardPolicy>
14 {
15  return m_vme->device();
16 }
17 
18 
19 
20 // registers are 32 bits on card, but only 16 bits used
21 // they are also BIG ENDIAN, hence bit shifts
22 template <class DAECardPolicy>
23 int DAE2Card<DAECardPolicy>::readRegister(unsigned long address, isisU32_t* value, DAEstatus& status, bool little_endian, bool retry)
24 {
25  int stat;
27  if (little_endian)
28  {
30  }
31  *value = 0;
32  address = makeAddress(address);
33  if (retry)
34  {
35  stat = m_vme->readU32(address, value, props, status);
36  }
37  else
38  {
39  stat = m_vme->readU32noRetry(address, value, props, status);
40  }
41  if (stat == ISISVME::Success)
42  {
43 // *value = (*value >> 16); // discard bottom 16 bits of junk
44  return 1;
45  }
46  else
47  {
48  return 0;
49  }
50 }
51 
52 template <class DAECardPolicy>
53 void DAE2Card<DAECardPolicy>::printRegister(const char* name, unsigned long address, std::ostream& os, bool print_bits_set)
54 {
55  isisU32_t value;
56  DAEstatus status;
57  readRegister(address, &value, status);
58  os << name << " (0x" << std::hex << address << ") value 0x" << value << std::dec;
59  if (print_bits_set)
60  {
61  std::bitset<8*sizeof(value)> value_bits((unsigned long long)value);
62  // os << " " << value_bits.to_string();
63  if (value_bits.any())
64  {
65  os << " (bits set:";
66  for(int i=0; i < value_bits.size(); ++i)
67  {
68  if (value_bits.test(i))
69  {
70  os << " " << i;
71  }
72  }
73  os << ")";
74  }
75  }
76  os << std::endl;
77 }
78 
79 template <class DAECardPolicy>
80 int DAE2Card<DAECardPolicy>::readRegister(unsigned long address, isisU16_t* value, DAEstatus& status, bool little_endian, bool retry)
81 {
83  if (little_endian)
84  {
86  }
87  int stat;
88 // isisU32_t temp = 0;
89  *value = 0;
90  address = makeAddress(address);
91  if (retry)
92  {
93  stat = m_vme->readU16(address, value, props, status);
94  }
95  else
96  {
97  stat = m_vme->readU16noRetry(address, value, props, status);
98  }
99  if (stat == ISISVME::Success)
100  {
101 // *value = (isisU16_t)(temp >> 16); // discard bottom 16 bits of junk
102  return 1;
103  }
104  else
105  {
106  return 0;
107  }
108 }
109 
110 // Read a 32 bit value from two 32 bit registers that
111  // contain 16 bit numbers
112  // address0 is low bits, address1 higher
113 template <class DAECardPolicy>
114  int DAE2Card<DAECardPolicy>::readRegister16As32(unsigned long address0, unsigned long address1, isisU32_t* value, DAEstatus& status, bool little_endian)
115  {
116  if (address0 == address1)
117  {
118  return readRegister(address0, value, status, little_endian);
119  }
120  else
121  {
122  isisU32_t value0, value1;
123  readRegister(address0, &value0, status, little_endian);
124  readRegister(address1, &value1, status, little_endian);
125  value0 &= 0xffff;
126  value1 &= 0xffff;
127  *value = (value1 << 16) | value0;
128  return 1;
129  }
130  }
131 
132  // write a 32 bit value to two 16 bit registers
133  // address0 is low bits, address1 higher
134 template <class DAECardPolicy>
135  int DAE2Card<DAECardPolicy>::writeRegister32As16(unsigned long address0, unsigned long address1, isisU32_t value, DAEstatus& status, bool little_endian)
136  {
137  if (address0 == address1)
138  {
139  return writeRegister(address0, value, status, little_endian);
140  }
141  else
142  {
143  isisU16_t value0, value1;
144  value0 = (isisU16_t)(value & 0xffff);
145  value1 = (isisU16_t)((value >> 16) & 0xffff);
146  writeRegister16(address0, value0, status, little_endian);
147  writeRegister16(address1, value1, status, little_endian);
148  return 1;
149  }
150  }
151 
152 
153 
154 template <class DAECardPolicy>
155 int DAE2Card<DAECardPolicy>::writeRegister(unsigned long address, isisU32_t value, DAEstatus& status, bool little_endian)
156 {
158  if (little_endian)
159  {
161  }
162  address = makeAddress(address);
163 // reverseEndian(&value); // registers are big endian
164  m_vme->writeU32(address, value, props, status);
165  return 1;
166 }
167 
168 template <class DAECardPolicy>
169 int DAE2Card<DAECardPolicy>::writeRegister16(unsigned long address, isisU16_t value, DAEstatus& status, bool little_endian)
170 {
172  if (little_endian)
173  {
175  }
176  address = makeAddress(address);
177 // reverseEndian(&value); // registers are big endian
178  m_vme->writeU16(address, value, props, status);
179  return 1;
180 }
181 
182 template <class DAECardPolicy>
183 int DAE2Card<DAECardPolicy>::setRegisterBits(unsigned long address, isisU32_t mask, bool preserve, DAEstatus& status, bool little_endian)
184 {
186  if (little_endian)
187  {
189  }
190  isisU32_t old_value;
191  address = makeAddress(address);
192  if (preserve)
193  {
194  m_vme->readU32(address, &old_value, props, status);
195  mask |= old_value;
196  }
197  return m_vme->writeU32(address, mask, props, status);
198 }
199 
200 template <class DAECardPolicy>
201 int DAE2Card<DAECardPolicy>::clearRegisterBits(unsigned long address, isisU32_t mask, DAEstatus& status, bool little_endian)
202 {
204  if (little_endian)
205  {
207  }
208  isisU32_t old_value;
209  address = makeAddress(address);
210  m_vme->readU32(address, &old_value, props, status);
211  mask = (old_value & ~mask);
212  return m_vme->writeU32(address, mask, props, status);
213 }
214 
215 template <class DAECardPolicy>
216 int DAE2Card<DAECardPolicy>::changeRegisterBits(unsigned long address, isisU32_t mask, bool set, bool check, DAEstatus& status, bool little_endian)
217 {
218  int stat;
219  if (set)
220  {
221  stat = setRegisterBits(address, mask, true, status, little_endian);
222  while( check && !registerBitsSet(address, mask, status, little_endian) )
223  {
224  status.addWarningVa(FAC_DAE, "retrying set of register %lu mask %lu", address, mask);
225  Sleep(100);
226  stat = setRegisterBits(address, mask, true, status, little_endian);
227  }
228  }
229  else
230  {
231  stat = clearRegisterBits(address, mask, status, little_endian);
232  while( check && !registerBitsClear(address, mask, status, little_endian) )
233  {
234  status.addWarningVa(FAC_DAE, "retrying clear of register %lu mask %lu", address, mask);
235  Sleep(100);
236  stat = clearRegisterBits(address, mask, status, little_endian);
237  }
238  }
239  return stat;
240 }
241 
242 template <class DAECardPolicy>
243 int DAE2Card<DAECardPolicy>::setAndClearRegisterBits(unsigned long address, isisU32_t mask, bool preserve, DAEstatus& status, bool little_endian)
244 {
246  if (little_endian)
247  {
249  }
250  isisU32_t old_value, val;
251  address = makeAddress(address);
252  if (preserve)
253  {
254  m_vme->readU32(address, &old_value, props, status);
255  val = mask | old_value;
256  m_vme->writeU32(address, val, props, status);
257  val = ~mask & old_value;
258  m_vme->writeU32(address, val, props, status);
259  }
260  else
261  {
262  m_vme->writeU32(address, mask, props, status);
263  m_vme->writeU32(address, 0, props, status);
264  }
265  return 0;
266 }
267 
268 template <class DAECardPolicy>
269 bool DAE2Card<DAECardPolicy>::registerBitsSet(unsigned long address, isisU32_t mask, DAEstatus& status, bool little_endian)
270 {
272  if (little_endian)
273  {
275  }
276  isisU32_t value;
277  address = makeAddress(address);
278  m_vme->readU32(address, &value, props, status);
279  if ((value & mask) == mask)
280  {
281  return true;
282  }
283  else
284  {
285  return false;
286  }
287 }
288 
289 template <class DAECardPolicy>
290 bool DAE2Card<DAECardPolicy>::registerBitsClear(unsigned long address, isisU32_t mask, DAEstatus& status, bool little_endian)
291 {
293  if (little_endian)
294  {
296  }
297  isisU32_t value;
298  address = makeAddress(address);
299  m_vme->readU32(address, &value, props, status);
300  if ((value & mask) == 0)
301  {
302  return true;
303  }
304  else
305  {
306  return false;
307  }
308 }
309 
310 
311 // look for TCG Time Bin Limit Register address, which should
312 // exist on all cards
313 // env card (run control register) and det card (tcg time bin limit)
314 // both at 0x40084
315 // period card has period register at 0x40088
316 template <class DAECardPolicy>
317 bool DAE2Card<DAECardPolicy>::isCardPresent(int position, ISISVME* vme, DAEstatus& dstatus)
318 {
319  isisU32_t value;
320  isisU16_t value16;
321  int status;
322  DAEstatus temp_stat;
323  unsigned long addr = makeAddress(position, FIRMVERS);
324  status = vme->readU32noRetry(addr, &value, ISISVME::TransferIORegisterSpace, temp_stat);
325  if ( (status == ISISVME::Success) )
326  {
327  return true;
328  }
329  temp_stat.clear(SEV_ERROR, SEV_GE);
330  addr = makeAddress(position, 0x8000000);
331  status = vme->readU32noRetry(addr, &value, ISISVME::TransferMemorySpace, temp_stat);
332  if (status == ISISVME::Success)
333  {
334  return true;
335  }
336 // this is TCG register, but it is not checked for in the getCardType
337 // whihc used memeory check instead, so change here to use just memory
338 // check otherwise may detect a card but not know its type
339 // temp_stat.clear(SEV_ERROR, SEV_GE);
340 // addr = makeAddress(position, 0x40084);
341 // status = vme->readU32noRetry(addr, &value, ISISVME::TransferIORegisterSpace, temp_stat);
342 // if ( (status == ISISVME::Success) )
343 // {
344 // return true;
345 // }
346  temp_stat.clear(SEV_ERROR, SEV_GE);
347  addr = makeAddress(position, 0x40088); // period card?
348  status = vme->readU16noRetry(addr, &value16, false, temp_stat);
349  if ( (status == ISISVME::Success) )
350  {
351  return true;
352  }
353  else
354  {
355  temp_stat.clear(SEV_ERROR, SEV_GE);
356  return false;
357  }
358 }
359 
360 template <class DAECardPolicy>
362 {
363  int status;
364  unsigned long addr;
365  isisU32_t value32;
366  isisU16_t value16;
367  CardType card_type;
368  firmware_version fw;
369  getFirmwareVersion(position, vme, &fw, dstatus);
370  card_type = DAE2Card::UnknownCard;
371  switch(fw.main_func)
372  {
373  case 0x1: // environment card
374  switch(fw.hard_type)
375  {
376  case 0x0:
377  case 0x1:
378  card_type = DAE2Card::EnvCard;
379  break;
380 
381  case 0x2:
382  card_type = DAE2Card::EnvPeriodCard;
383  break;
384  }
385  break;
386 
387  case 0x2: // detector card
388  switch(fw.hard_type)
389  {
390  case 0x0:
391  case 0x1:
392  case 0x2:
393  case 0x4:
394  card_type = DAE2Card::NeutronDetectorCard;
395  break;
396 
397  case 0x3:
398  card_type = DAE2Card::MuonDetectorCard;
399  break;
400  }
401  break;
402 
403  case 0x3: // Other (defined)
404  switch(fw.hard_type)
405  {
406  case 0x0:
407  card_type = DAE2Card::MuonPeriodCard;
408  break;
409  }
410  break;
411  }
412  if (card_type != DAE2Card::UnknownCard)
413  {
414  return card_type;
415  }
416  // old detector card maybe?
417  addr = makeAddress(position, 0x8000000);
418  status = vme->readU32noRetry(addr, &value32, ISISVME::TransferMemorySpace, dstatus);
419  if (status == ISISVME::Success)
420  {
422  }
423  else
424  {
425  dstatus.clear(SEV_ERROR, SEV_GE);
426  }
427  // old period card maybe?
428  addr = makeAddress(position, 0x40088);
429  status = vme->readU16noRetry(addr, &value16, true, dstatus);
430  if (status == ISISVME::Success)
431  {
433  }
434  else
435  {
436  dstatus.clear(SEV_ERROR, SEV_GE);
437  }
438  // old environment card maybe?
439 // addr = makeAddress(position, 0x14);
440 // status = vme->readU16noRetry(addr, &value16, true, dstatus);
441 // if (status == ISISVME::Success)
442 // {
443 // return DAE2Card::EnvCard;
444 // }
445 // else
446 // {
447 // dstatus.clear(SEV_ERROR, SEV_GE);
448 // }
449  return DAE2Card::UnknownCard;
450 }
451 
452 template <class DAECardPolicy>
453 void DAE2Card<DAECardPolicy>::printStatus(std::ostream& os, DAEstatus& dstatus)
454 {
455  os << "--- DAE2 card with address/position/number = " << m_position << " ---" << std::endl;
456  os << getFirmwareVersionAsString(dstatus) << std::endl;
457 }
458 
459 template <class DAECardPolicy>
461 {
462  std::stringstream sstr;
463  firmware_version fw;
464  getFirmwareVersion(m_position, m_vme, &fw, dstatus);
465  sstr << "Firmware register: 0x" << std::hex << *(isisU32_t*)&fw << std::dec << "\n";
466  switch(fw.main_func)
467  {
468  case 0x0: // other (not defined)
469  sstr << "Hardware type: OTHER CARD (Not Defined)\n";
470  break;
471 
472  case 0x1: // environment card
473  switch(fw.hard_type)
474  {
475  case 0x0:
476  sstr << "Hardware type: ENVIRONMENT CARD (Dedicated)\n";
477  break;
478  case 0x1:
479  sstr << "Hardware type: ENVIRONMENT CARD (Configured from detector card)\n";
480  break;
481  case 0x2:
482  sstr << "Hardware type: ENVIRONMENT CARD (With period functions)\n";
483  break;
484  default:
485  sstr << "Hardware type: ENVIRONMENT CARD (UNKNOWN)\n";
486  break;
487  }
488  break;
489 
490  case 0x2: // detector card
491  switch(fw.hard_type)
492  {
493  case 0x0:
494  sstr << "Hardware type: DETECTOR CARD (Neutron, 1 DIM)\n";
495  break;
496  case 0x1:
497  sstr << "Hardware type: DETECTOR CARD (Neutron, 2 DIM)\n";
498  break;
499  case 0x2:
500  sstr << "Hardware type: DETECTOR CARD (Neutron, 16 DIM)\n";
501  break;
502  case 0x3:
503  sstr << "Hardware type: DETECTOR CARD (Muon, 4 DIM)\n";
504  break;
505  case 0x4:
506  sstr << "Hardware type: DETECTOR CARD (Neutron, 32 DIM)\n";
507  break;
508  default:
509  sstr << "Hardware type: DETECTOR CARD (UNKNOWN)\n";
510  break;
511  }
512  break;
513 
514  case 0x3:
515  switch(fw.hard_type)
516  {
517  case 0x0:
518  sstr << "Hardware type: OTHER CARD (Muon Period Card)\n";
519  break;
520  default:
521  sstr << "Hardware type: OTHER CARD (Defined, but UNKNOWN)\n";
522  break;
523  }
524  break;
525 
526  default: // should never get here as all cases covered above
527  sstr << "Hardware type: ERROR\n";
528  break;
529  }
530  sstr << "Firmware sub version = " << fw.sub_ver << "\n";
531  sstr << "Firmware minor version = " << fw.minor_ver << "\n";
532  sstr << "Firmware hardware version = " << fw.hard_ver;
533  return sstr.str();
534 }
535 
536 template <class DAECardPolicy>
538 {
539  unsigned long addr = makeAddress(position, FIRMVERS);
540  int status = vme->readU32noRetry(addr, (isisU32_t*)fw, ISISVME::TransferIORegisterSpace, dstatus);
541  if (status == ISISVME::Success)
542  {
543  return 1;
544  }
545  else
546  {
547  // zero the structure ... this will set
548  // fw->hard_type = 0 which is "Other (not defined)"
549  memset(fw, 0, sizeof(firmware_version));
550  dstatus.clear(SEV_ERROR, SEV_GE);
551  }
552  return 0;
553 }
554 
555 
556 template class DAE2Card<DAE2CardPolicy>;
557 template class DAE2Card<DAE2DetCardPolicy>;
558 template class DAE2Card<DAE2EnvPeriodPolicy>;
559 
560 template class DAE2Card<DAE3CardPolicy>;
561 template class DAE2Card<DAE3DetCardPolicy>;
562 template class DAE2Card<DAE3EnvPeriodPolicy>;
563 
564 const std::string DAE2CardPolicy::card_policy_name = "DAE2CardPolicy";
565 const std::string DAE2DetCardPolicy::det_card_policy_name = "DAE2DetCardPolicy";
566 const std::string DAE2EnvPeriodPolicy::env_period_policy_name = "DAE2EnvPeriodPolicy";
567 
568 const std::string DAE3CardPolicy::card_policy_name = "DAE3CardPolicy";
569 const std::string DAE3DetCardPolicy::det_card_policy_name = "DAE3DetCardPolicy";
570 const std::string DAE3EnvPeriodPolicy::env_period_policy_name = "DAE3EnvPeriodPolicy";
571 
572 const std::string DAE2Policy::policy_name = "DAE2Policy";
573 const std::string DAE3Policy::policy_name = "DAE3Policy";
574 
575 const std::string DAE2CardPolicy::card_type = "DAE2";
576 const std::string DAE3CardPolicy::card_type = "DAE3";
virtual int readU32noRetry(unsigned long address, isisU32_t *data32, TransferProps props, DAEstatus &dstatus)=0
uint32_t TransferProps
combination of TransferProp values
Definition: isisvme.h:16
static const std::string policy_name
Definition: dae2_policy.h:151
#define FAC_DAE
unsigned hard_type
Definition: dae2_card.h:21
static const std::string card_type
Definition: dae2_policy.h:19
static const std::string card_type
Definition: dae3_policy.h:21
std::string getFirmwareVersionAsString(DAEstatus &status)
Definition: dae2_card.cpp:460
int setRegisterBits(unsigned long address, isisU32_t mask, bool preserve, DAEstatus &status, bool little_endian=false)
Definition: dae2_card.cpp:183
unsigned long isisU32_t
Definition: isisvme_types.h:8
static const std::string card_policy_name
Definition: dae3_policy.h:20
static const std::string env_period_policy_name
static CardType getCardType(int position, ISISVME *vme, DAEstatus &dstatus)
Definition: dae2_card.cpp:361
bool registerBitsSet(unsigned long address, isisU32_t mask, DAEstatus &status, bool little_endian=false)
Definition: dae2_card.cpp:269
static const std::string policy_name
Definition: dae3_policy.h:165
int clearRegisterBits(unsigned long address, isisU32_t mask, DAEstatus &status, bool little_endian=false)
Definition: dae2_card.cpp:201
virtual void printStatus(std::ostream &os, DAEstatus &dstatus)
Definition: dae2_card.cpp:453
DAE2Card(int position, ISISVME *vme, DAEstatus &status)
Definition: dae2_card.cpp:7
#define SEV_ERROR
int writeRegister(unsigned long address, isisU32_t value, DAEstatus &status, bool little_endian=false)
Definition: dae2_card.cpp:155
virtual int readU16noRetry(unsigned long address, isisU16_t *data16, TransferProps props, DAEstatus &dstatus)=0
int clear(int severity, int direction, bool reset_overall_severity=true)
Definition: DAEstatus.cpp:201
static const std::string det_card_policy_name
Definition: dae2_policy.h:45
static const std::string det_card_policy_name
Definition: dae3_policy.h:57
static bool isCardPresent(int position, ISISVME *vme, DAEstatus &status)
Definition: dae2_card.cpp:317
static const std::string card_policy_name
Definition: dae2_policy.h:18
unsigned sub_ver
Definition: dae2_card.h:18
int readRegister(unsigned long address, isisU32_t *value, DAEstatus &status, bool little_endian=false, bool retry=true)
Definition: dae2_card.cpp:23
int setAndClearRegisterBits(unsigned long address, isisU32_t mask, bool preserve, DAEstatus &status, bool little_endian=false)
Definition: dae2_card.cpp:243
unsigned short isisU16_t
Definition: isisvme_types.h:7
int addWarningVa(int facility, const char *format,...)
Definition: DAEstatus.cpp:106
std::string daeDevice() const
Definition: dae2_card.cpp:13
unsigned hard_ver
Definition: dae2_card.h:20
int changeRegisterBits(unsigned long address, isisU32_t mask, bool set, bool check, DAEstatus &status, bool little_endian=false)
Definition: dae2_card.cpp:216
int writeRegister16(unsigned long address, isisU16_t value, DAEstatus &status, bool little_endian=false)
Definition: dae2_card.cpp:169
static int getFirmwareVersion(int position, ISISVME *vme, firmware_version *fw, DAEstatus &status)
Definition: dae2_card.cpp:537
void setLoggerName(const std::string &logger_name)
Definition: IsisBase.h:17
unsigned main_func
Definition: dae2_card.h:22
static const std::string env_period_policy_name
int writeRegister32As16(unsigned long address0, unsigned long address1, isisU32_t value, DAEstatus &status, bool little_endian=false)
Definition: dae2_card.cpp:135
int readRegister16As32(unsigned long address0, unsigned long address1, isisU32_t *value, DAEstatus &status, bool little_endian=false)
Definition: dae2_card.cpp:114
#define SEV_GE
bool registerBitsClear(unsigned long address, isisU32_t mask, DAEstatus &status, bool little_endian=false)
Definition: dae2_card.cpp:290
unsigned minor_ver
Definition: dae2_card.h:19
void printRegister(const char *name, unsigned long address, std::ostream &os, bool print_bits_set=false)
Definition: dae2_card.cpp:53