ICP  1
env_period_card.cpp
Go to the documentation of this file.
1 #include "stdafx.h"
2 #include "DAEstatus.h"
3 #include "icputils.h"
4 #include "isisvme.h"
5 #include "env_period_card.h"
6 #include "dae_events.h"
7 
10 
12 // period card
14 
15 template <class EnvPeriodPolicy>
16 EnvPeriodCard<EnvPeriodPolicy>::EnvPeriodCard(int position, ISISVME* vme, DAEstatus& status) : DAE2Card(position, vme, status), m_options(0)
17 {
18  setLoggerName("EnvPeriodCard");
19  std::ostringstream message;
20  updateOptions(status);
21  printStatus(message, status);
22  status.addInfo(FAC_ENVCARD, message.str());
24  {
25  LOGSTR_WARNING("SRAM memory checking is currently DISABLED");
26  }
28  {
29  LOGSTR_INFORMATION("Event mode timer");
30  }
31 }
32 
34 {
35  int bit;
36  const char* unset;
37  const char* set;
38 };
39 
40 // list of bit number, unset meaning, set meaning
41 static const period_modes mode_list[] = {
42  {15, "", "Reset Period card" },
43  {13, "", "Clear Period Counters" },
44  {11, "", "Muon MS Mode" },
45 // {10, "Extract Trigger Veto Disabled", "Extract Trigger Veto Enabled" },
46 // {9, "50Hz Veto Disabled", "50Hz Veto Enabled" },
47 // {8, "Internal Period Clock Mode", "External Period Clock Mode" },
48  {7, "", "Multiple Period sequence complete" },
49  {6, "Single period sequence mode", "Multiple period sequence mode" },
50  {5, "Internal period control mode", "External period control mode" },
51  {4, "Non-period mode", "Period mode"},
52  {3, "", "Run ended AND period sequence completed" },
53  {2, "", "Period sequence complete" },
54  {1, "", "End after period sequence complete has been requested" },
55 };
56 
57 template <class EnvPeriodPolicy>
59 {
60  // period card
61  DAE2Card::printStatus(os, status);
62  isisU32_t value, value1;
63  isisU32_t value32;
64  isisU16_t value16;
65  int i, nper;
66  os << "This is a " << EnvPeriodPolicy::card_type << " combined ENVIRONMENT and PERIOD card" << std::endl;
67  readRegister(ALT1SFV, &value32, status);
68  value32 &= 0xff; // only 8 bits used, split 4/4
69  os << "ALT1 firmware version = " << (value32 >> 4) << "." << (value32 & 0x0f) << std::endl;
70  os << "Current period number = " << getCurrentPeriodNumber(status) << (inDwellPeriod(status) ? " (DWELL)" : " (DAQ)") << std::endl;
71  nper = getNumberOfPeriods(status);
72  os << "Number of periods = " << nper << std::endl;
73  readRegister(PSCNT, &value32, status);
74  os << "Period sequence number = " << value32 << std::endl;
75 // readRegister(PSLR, &value16, status);
76 // os << "Period sequence limit register = " << value16 << std::endl;
77 // getExtractTriggerVetoCount(&value32, status);
78 // os << "Extract trigger veto count = " << value32 << std::endl;
79  readRegister(PCREG, &value16, status);
80 // readRegister(PCREG, &value32, status);
81 // value16 = (isisU16_t)value32;
82  os << "Summary of period control register, value = 0x" << std::hex << value16 << std::dec << std::endl;
83  for(i=0; i<sizeof(mode_list)/sizeof(period_modes); i++)
84  {
85  if (value16 & (1 << mode_list[i].bit))
86  {
87  os << "Bit " << mode_list[i].bit << " is SET (" << mode_list[i].set << ")" << std::endl;
88  }
89  else
90  {
91  os << "Bit " << mode_list[i].bit << " is CLEAR (" << mode_list[i].unset << ")" << std::endl;
92  }
93  }
94  // nper may be 0 from an uninitialised card
95  if (nper < 1)
96  {
97  nper = 1;
98  }
99  isisU16_t* frames_needed = new isisU16_t[nper];
100  isisU32_t* good_frames = new isisU32_t[nper];
101  isisU32_t* raw_frames = new isisU32_t[nper];
102  isisU16_t* dwell_flags = new isisU16_t[nper];
103  isisU32_t* outputs = new isisU32_t[nper];
104  readPERLUT(dwell_flags, frames_needed, nper, status);
105  readOUTLUT(outputs, nper, status);
106  getRawFrames(0, nper, raw_frames, status);
107  getGoodFrames(0, nper, good_frames, status);
108  os << "Summary of period card programming (1st 16 max)" << std::endl;
109  for(i=0; i< (nper < 16 ? nper : 16); i++)
110  {
111  os << "Period " << i << (dwell_flags[i] != 0 ? " (DWELL)" : " (DAQ)") << std::endl;
112  os << "\tRequested frames = " << frames_needed[i] << " logic signal output = 0x" << std::hex << outputs[i] << std::dec << std::endl;
113  os << "\tCurrent counters (should always be ZERO for DWELL): raw = " << raw_frames[i] << " good = " << good_frames[i] << std::endl;
114  }
115  delete[] frames_needed;
116  delete[] good_frames;
117  delete[] raw_frames;
118  delete[] outputs;
119  delete[] dwell_flags;
120  readRegister(RCONTROL, &value, status);
121  os << "RC register value = " << std::hex << "0x" << value << std::dec << std::endl;
122  os << "Status: " << (value & RCSTART ? "Running" : "Stopped") << std::endl;
123  os << "Event mode: " << (value & RCEVENTMODE ? "Enabled" : "Disabled") << std::endl;
124  os << "Frame Sync: ";
125  switch(value & RCFSSEL)
126  {
127  case 0:
128  os << "Internal";
129  break;
130  case RCFSSMP:
131  os << "SMP";
132  break;
133  case RCFSTOF:
134  os << "ISIS TOF";
135  break;
136  case RCFSTOF1P:
137  os << "ISIS TOF (1st pulse)";
138  break;
139  case RCFSMUONCK:
140  os << "Muon Cerenkov";
141  if (value & RCFSSCH2)
142  {
143  os << " (2nd pulse)";
144  }
145  else
146  {
147  os << " (1st pulse)";
148  }
149  break;
150  case RCFSMUONMS:
151  os << "Muon MS mode";
152  break;
153 
154  default:
155  os << "Error";
156  break;
157  }
158  os << std::endl;
159  getFrameSyncDelay(&value1, status);
160  os << "Frame sync delay: " << value1 << "\n";
161  printVetoDetails(os, status);
162 
163  getGoodFrames(&value1, status);
164  getRawFrames(&value, status);
165  os << "GOOD/RAW frames: " << value1 << "/" << value << "\n";
166  os << "GOOD/TOTAL uamph: " << getGoodUAmpHours(status) << "/" << getGoodUAmpHours(status) << "\n";
167  os << "Period Type: " << (usingHardwarePeriods(status) ? "Hardware" : "Software") << "\n";
168  if (checkOptions(RotateFrameCountersRight))
169  {
170  os << "Single frame workaround enabled\n";
171  }
172  os << "Current DAE frame time drift (icp - dae) = " << frameTimerDrift(status) / 1000.0 << " ms\n";
173  if (checkOptions(NoCheckSRAM))
174  {
175  os << "WARNING: SRAM memory checking is DISABLED\n";
176  }
177  // print period type
178 }
179 
180 template <class EnvPeriodPolicy>
182 {
183  int i;
184  isisU32_t veto_reg, frames;
185  readRegister(RVETO, &veto_reg, status);
186  for(i=0; veto_details[i].name != NULL; i++)
187  {
188  readRegister(veto_details[i].counter_addr, &frames, status);
189  os << veto_details[i].name << " is " << ((veto_reg & veto_details[i].mask) != 0 ? "ENABLED (vetoed " : "DISABLED (counted ") << frames << ") frames\n";
190  }
191  return DAEstatus::Success;
192 }
193 
194 template <class EnvPeriodPolicy>
196 {
197  return clearRunControlBits(RCPERSZEQZERO, status);
198 }
199 
200 template <class EnvPeriodPolicy>
202 {
203  return setRunControlBits(RCPERSZEQZERO, true, status);
204 }
205 
207 template <class EnvPeriodPolicy>
209 {
210  static time_t last_call;
211  static isisU32_t vframes1[100], rf1;
212  int i;
213  isisU32_t veto_reg, rf2, vframes2[100], poll_time;
214  double rfdiff;
215  int nveto;
216  for(nveto = 0; veto_details[nveto].name != NULL; ++nveto)
217  ;
218  readRegister(RVETO, &veto_reg, status);
219  for(i=0; i < nveto; i++)
220  {
221  readRegister(veto_details[i].counter_addr, &(vframes2[i]), status);
222  }
223  getRawFrames(&rf2, status);
224  rfdiff = rf2 - rf1;
225  rf1 = rf2; // save value
226  if (rfdiff <= 0)
227  {
228  rfdiff = 1; // stop division by zero error if ISIS not running
229  rf2 = 1;
230  }
231  poll_time = time(NULL) - last_call;
232  time(&last_call);
233  for(i=0; i < nveto; i++)
234  {
235  if ((veto_reg & veto_details[i].mask) != 0)
236  {
237  os << veto_details[i].name << " vetoed " <<
238  (int)(100.0 * (vframes2[i] - vframes1[i]) / rfdiff) <<
239  "% (last " << poll_time << " seconds), " <<
240  (int)(100.0 * vframes2[i] / rf2) <<
241  "% (since run start)\n";
242  }
243  vframes1[i] = vframes2[i];
244  }
245  return DAEstatus::Success;
246 }
247 
248 template <class EnvPeriodPolicy>
250 {
251  return setRegisterBits(PCREG, mask, preserve, status);
252 }
253 
254 template <class EnvPeriodPolicy>
256 {
257  return clearRegisterBits(PCREG, mask, status);
258 }
259 
260 template <class EnvPeriodPolicy>
262 {
263  return setAndClearRegisterBits(PCREG, mask, preserve, status);
264 }
265 
266 //int EnvPeriodCard<EnvPeriodPolicy>::clearVetoCounters(DAEstatus& status)
267 //{
268 // return setAndClearPeriodControlBits(PCCLRVETO, true, status);
269 //}
270 
271 //int EnvPeriodCard<EnvPeriodPolicy>::getExtractTriggerVetoCountLow(isisU16_t* value, DAEstatus& status)
272 //{
273 // return readRegister(EXTTRIGVC0, value, status);
274 //}
275 
276 //int EnvPeriodCard<EnvPeriodPolicy>::getExtractTriggerVetoCountHigh(isisU16_t* value, DAEstatus& status)
277 //{
278 // return readRegister(EXTTRIGVC1, value, status);
279 //}
280 
281 //int EnvPeriodCard<EnvPeriodPolicy>::getExtractTriggerVetoCount(isisU32_t* value, DAEstatus& status)
282 //{
283 // return readRegister16As32(EXTTRIGVC0, EXTTRIGVC1, value, status);
284 //}
285 
286 //int EnvPeriodCard<EnvPeriodPolicy>::enableExtractTriggerVeto(DAEstatus& status)
287 //{
288 // return setPeriodControlBits(PCEXTTRIG, true, status);
289 //}
290 
291 //int EnvPeriodCard<EnvPeriodPolicy>::disableExtractTriggerVeto(DAEstatus& status)
292 //{
293 // return clearPeriodControlBits(PCEXTTRIG, status);
294 //}
295 
296 template <class EnvPeriodPolicy>
298 {
299  return writeRegister16(LOOKTAR, TAROUTLUT, status);
300 }
301 
302 template <class EnvPeriodPolicy>
304 {
305  return writeRegister16(LOOKTAR, TARPERLUT, status);
306 }
307 
308 template <class EnvPeriodPolicy>
310 {
311  return writeRegister16(LOOKTAR, 0, status);
312 }
313 
314 template <class EnvPeriodPolicy>
316 {
317  isisU16_t period;
318  int stat = readRegister(MPCNT, &period, status);
319  period &= 0x3fff;
320  return period;
321 }
322 
323 template <class EnvPeriodPolicy>
325 {
326  isisU16_t period;
327  readRegister(MPCNT, &period, status);
328  return ((period & (1 << 14)) != 0);
329 }
330 
331 template <class EnvPeriodPolicy>
333 {
334  return writeRegister16(MPLIM, n, status);
335 }
336 
337 template <class EnvPeriodPolicy>
339 {
340  isisU16_t n;
341  readRegister(MPLIM, &n, status);
342  if (n >= MAX_NUM_PERIODS)
343  {
344  return MAX_NUM_PERIODS;
345  }
346  else if (n <= 0)
347  {
348  return 1;
349  }
350  else
351  {
352  return n; // as this is a period number limit register
353  }
354 }
355 
356 template <class EnvPeriodPolicy>
358 {
359  isisU32_t n;
360  readRegister(PSCNT, &n, status);
361  return n;
362 }
363 
364 template <class EnvPeriodPolicy>
366 {
367  return setAndClearPeriodControlBits(PCRESET, true, status);
368 }
369 
370 template <class EnvPeriodPolicy>
372 {
373 // setAndClearRegisterBits(MAT_1, (1 << 12), true, status);
374  return setAndClearPeriodControlBits(PCCLRPC, true, status);
375 }
376 
377 //int EnvPeriodCard<EnvPeriodPolicy>::enable50HzVeto(DAEstatus& status)
378 //{
379 // return setPeriodControlBits(PC50HZENAB, true, status);
380 //}
381 
382 //int EnvPeriodCard<EnvPeriodPolicy>::disable50HzVeto(DAEstatus& status)
383 //{
384 // return clearPeriodControlBits(PC50HZENAB, status);
385 //}
386 
387 //int EnvPeriodCard<EnvPeriodPolicy>::setInternalPeriodClockMode(DAEstatus& status)
388 //{
389 // return clearPeriodControlBits(PCEXTPERCLK, status);
390 //}
391 
392 //int EnvPeriodCard<EnvPeriodPolicy>::setExternalPeriodClockMode(DAEstatus& status)
393 //{
394 // return setPeriodControlBits(PCEXTPERCLK, true, status);
395 //}
396 
397 template <class EnvPeriodPolicy>
399 {
400  return clearPeriodControlBits(PCMULENAB, status);
401 }
402 
403 template <class EnvPeriodPolicy>
405 {
406  writeRegister(PSLR, nseq, status);
407  return setPeriodControlBits(PCMULENAB, true, status);
408 }
409 
410 template <class EnvPeriodPolicy>
412 {
413  if (external_mode)
414  {
415  return setPeriodControlBits(PCENAB | PCEXTENAB, true, status);
416  }
417  else
418  {
419  clearPeriodControlBits(PCEXTENAB, status);
420  return setPeriodControlBits(PCENAB, true, status);
421  }
422 }
423 
424 template <class EnvPeriodPolicy>
426 {
427  return clearPeriodControlBits(PCENAB, status);
428 }
429 
430 template <class EnvPeriodPolicy>
432 {
433  setOptions(MSMode);
434  return setPeriodControlBits(PCMSM, true, status);
435 }
436 
437 template <class EnvPeriodPolicy>
439 {
440  clearOptions(MSMode);
441  return clearPeriodControlBits(PCMSM, status);
442 }
443 
444 
445 template <class EnvPeriodPolicy>
447 {
448  return setPeriodControlBits(PCENDAFTER, true, status);
449 }
450 
451 template <class EnvPeriodPolicy>
453 {
454  isisU32_t value;
455  readRegister(PCREG, &value, status);
456  if (value & PCENDSEQCOMP)
457  {
458  clearPeriodControlBits(PCENDAFTER, status);
459  return true;
460  }
461  else
462  {
463  return false;
464  }
465 }
466 
467 template <class EnvPeriodPolicy>
469 {
470  isisU32_t value;
471  readRegister(PCREG, &value, status);
472  if ( ((value & PCENDSEQCOMP) == 0) && ((value & PCENDAFTER) != 0) )
473  {
474  return true;
475  }
476  else
477  {
478  return false;
479  }
480 }
481 
482 template <class EnvPeriodPolicy>
484 {
485  if (registerBitsSet(PCREG, (PCENAB | PCMULENAB | PCMULCOMP), status))
486  {
487  return true;
488  }
489  else
490  {
491  return false;
492  }
493 }
494 
495 template <class EnvPeriodPolicy>
497 {
498  clearPeriodControlBits(PCENDAFTER, status);
499 }
500 
501 // dwell_flag is 0 for DAQ period, 1 for DWELL period
502 template <class EnvPeriodPolicy>
503 int EnvPeriodCard<EnvPeriodPolicy>::programPERLUT(isisU16_t* dwell_flags, isisU16_t* frames, int nperiod, DAEstatus& status)
504 {
505  int i;
507  isisU32_t* pdata = new isisU32_t[nperiod];
508  bool single_frames_only = true;
509  for(i=0; i<nperiod; i++)
510  {
511  if (frames[i] != 1)
512  {
513  single_frames_only = false;
514  }
515  pdata[i] = ((frames[i]) & 0xffff) + (dwell_flags[i] != 0 ? (1 << 31) : 0);
516  }
517  // disable workaround
518  single_frames_only = false;
519  if (single_frames_only && checkOptions(MSMode))
520  {
521  setOptions(RotateFrameCountersRight);
522  }
523  else
524  {
525  clearOptions(RotateFrameCountersRight);
526  }
527  lookupAccessPERLUT(status);
528  zeroMemory<isisU32_t>(PERLUTSTART, PERLUTSIZE, 0xffffffff, props, status);
529  writeMemory(PERLUTSTART, pdata, nperiod, 0xffffffff, props, status);
530  lookupFinished(status);
531  delete []pdata;
532  return 0;
533 }
534 
535 template <class EnvPeriodPolicy>
536 int EnvPeriodCard<EnvPeriodPolicy>::readPERLUT(isisU16_t* dwell_flags, isisU16_t* frames, int nperiod, DAEstatus& status)
537 {
538  int i;
540  isisU32_t* pdata = new isisU32_t[nperiod];
541  lookupAccessPERLUT(status);
542  readMemory(PERLUTSTART, pdata, nperiod, props, status);
543  lookupFinished(status);
544  for(i=0; i<nperiod; i++)
545  {
546  frames[i] = (isisU16_t)(pdata[i] & 0xffff); // remove dwell flag
547  dwell_flags[i] = ( (pdata[i] & (1 << 31)) ? 1 : 0 );
548  }
549  delete []pdata;
550  return 0;
551 }
552 
553 // may also need to duplicate up last value in location n+1
554 // in case counter in DAE increemnts too far briefly before reset
555 template <class EnvPeriodPolicy>
557 {
558  lookupAccessOUTLUT(status);
560  zeroMemory<isisU32_t>(OUTLUTSTART, OUTLUTSIZE, OUTLUTMASK, props, status);
561  writeMemory(OUTLUTSTART, outputs, nperiod, OUTLUTMASK, props, status);
562 // also write last output value to n+1 location; this is a workaround to catch the small
563 // amout of time that it might get read between a period increment and a period reset
564 // tmp32 = outputs[nperiod-1]; // write last value again
565 // writeMemory(OUTLUTSTART + 4*nperiod, &tmp32, 1, 0xffffffff, false, false, status);
566  lookupFinished(status);
567  return 0;
568 }
569 
570 template <class EnvPeriodPolicy>
572 {
573  int i;
575  lookupAccessOUTLUT(status);
576 // we seem to need to start the outlut at address+1
577  readMemory(OUTLUTSTART, outputs, nperiod, props, status);
578  lookupFinished(status);
579  for(i=0; i<nperiod; i++)
580  {
581  outputs[i] &= OUTLUTMASK; // remove junk from top bits if required
582  }
583  return 0;
584 }
585 
586 template <class EnvPeriodPolicy>
588 {
590  uint32_t check_mask0 = (checkOptions(NoCheckSRAM) ? 0x0 : 0xffffffff);
591  zeroMemory<isisU32_t>(RFCNT0START, RFCNT0SIZE, check_mask0, props, status);
592  zeroMemory<isisU32_t>(GFCNT0START, GFCNT0SIZE, check_mask0, props, status);
593  return 0;
594 }
595 
596 template <class EnvPeriodPolicy>
598 {
600  EnvPeriodPolicy::ppp_memory_t check_mask0 = ( checkOptions(NoCheckSRAM) ? 0x0 : ~(static_cast<EnvPeriodPolicy::ppp_memory_t>(0)) );
601  uint32_t check_mask1 = (checkOptions(NoCheckSRAM) ? 0x0 : 0x0000ffff);
602  zeroMemory<EnvPeriodPolicy::ppp_memory_t>(RPCNT0START, RPCNT0SIZE, check_mask0, props, status);
603  zeroMemory<EnvPeriodPolicy::ppp_memory_t>(GPCNT0START, GPCNT0SIZE, check_mask0, props, status);
604 #if 0
605  if (RPCNT1START != RPCNT0START && RPCNT1SIZE > 0)
606  {
607  zeroMemory(RPCNT1START, RPCNT1SIZE, check_mask1, false, false, status); // only 16 bits used
608  zeroMemory(GPCNT1START, GPCNT1SIZE, check_mask1, false, false, status); // only 16 bits used
609  }
610 #endif
611  return 0;
612 }
613 
614 // spare SRAM counters
615 template <class EnvPeriodPolicy>
617 {
619  uint32_t check_mask0 = (checkOptions(NoCheckSRAM) ? 0x0 : 0xffffffff);
620  uint32_t check_mask1 = (checkOptions(NoCheckSRAM) ? 0x0 : 0x0000ffff);
621  if (SPARE0SIZE > 0)
622  {
623  zeroMemory<isisU32_t>(SPARE0START, SPARE0SIZE, check_mask0, props, status);
624  }
625  if (SPARE1SIZE > 0)
626  {
627  zeroMemory<isisU32_t>(SPARE1START, SPARE1SIZE, check_mask1, props, status); // only 16 bits used
628  }
629  return 0;
630 }
631 
632 template <class EnvPeriodPolicy>
634 {
635  return getRawFrames(period, 1, frames, status);
636 }
637 
638 template <class EnvPeriodPolicy>
640 {
641  return getGoodFrames(period, 1, frames, status);
642 }
643 
644 template <class EnvPeriodPolicy>
646 {
647  return getRequestedFrames(period, 1, frames, status);
648 }
649 
650 template <class EnvPeriodPolicy>
651 int EnvPeriodCard<EnvPeriodPolicy>::getRequestedFrames(int period_start, int nperiod, isisU32_t frames[], DAEstatus& status)
652 {
653  int i;
655  lookupAccessPERLUT(status);
656  readMemory(PERLUTSTART+4*period_start, frames, nperiod, props, status);
657  lookupFinished(status);
658  for(i=0; i<nperiod; i++)
659  {
660  frames[i] = (frames[i] & 0xffff); // remove dwell flag
661  }
662  return 0;
663 }
664 
666 template <class EnvPeriodPolicy>
667 int EnvPeriodCard<EnvPeriodPolicy>::getRawFrames(int period_start, int nperiod, isisU32_t frames[], DAEstatus& status)
668 {
669  int i, n;
671 // int seq = getCurrentPeriodSequence(status);
672 // isisU32_t* req_frames = new isisU32_t[nperiod];
673 // getRequestedFrames(period_start, nperiod, req_frames, status);
674  if (!checkOptions(RotateFrameCountersRight))
675  {
676  readMemory(RFCNT0START + 4*period_start, frames, nperiod, props, status);
677  return status.result();
678  }
679 // rotate counters
680 // sram 0 1 2 3
681 // nexus 1 2 3 0
682  n = getNumberOfPeriods(status);
683  isisU32_t* tmp_f = new isisU32_t[n];
684  readMemory(RFCNT0START, tmp_f, n, props, status);
685  for(i = 0; i < nperiod; i++)
686  {
687  frames[i] = tmp_f[(i + period_start + 1) % n];
688  }
689  delete[] tmp_f;
690 
691 // not needed now
692 // for(i=0; i<nperiod; i++)
693 // {
694 // frames[i] += (seq * req_frames[i]);
695 // }
696 // delete[] req_frames;
697  return status.result();
698 }
699 
700 template <class EnvPeriodPolicy>
701 int EnvPeriodCard<EnvPeriodPolicy>::getGoodFrames(int period_start, int nperiod, isisU32_t frames[], DAEstatus& status)
702 {
703  int i, j, n;
705 // int seq = getCurrentPeriodSequence(status);
706 // isisU32_t* req_frames = new isisU32_t[nperiod];
707 // getRequestedFrames(period_start, nperiod, req_frames, status);
708  if (!checkOptions(RotateFrameCountersRight))
709  {
710 // orig
711 // readMemory(GFCNT0START + 4*period_start, frames, nperiod, false, false, status);
712 
713  // workaround for Matt
714  // the good frames register for a dwell period should have 1 frame per sequence in it
715  // if it has more than this then it has stolen them from the previos DAQ period and this
716  // needs to be allowed for.
717  n = getNumberOfPeriods(status);
718  isisU32_t* tmp_f = new isisU32_t[n];
719  readMemory(GFCNT0START, tmp_f, n, props, status);
720  isisU16_t* dwell_flags = new isisU16_t[n];
721  isisU16_t* frames_requested = new isisU16_t[n];
722  int seq = getCurrentPeriodSequence(status);
723  readPERLUT(dwell_flags, frames_requested, n, status);
724  for(i=0; i<n; i++)
725  {
726  j = (i + 1) % n;
727  if ( (dwell_flags[i] == 0) && (dwell_flags[j] != 0) && (tmp_f[j] > seq) )
728  {
729  tmp_f[i] = tmp_f[i] + (tmp_f[j] - seq);
730  }
731  }
732  for(i=0; i<nperiod; i++)
733  {
734  frames[i] = tmp_f[i+period_start];
735  }
736  delete[] dwell_flags;
737  delete[] frames_requested;
738  delete[] tmp_f;
739  return status.result();
740  }
741 // rotate counters
742 // sram 0 1 2 3
743 // nexus 1 2 3 0
744  n = getNumberOfPeriods(status);
745  isisU32_t* tmp_f = new isisU32_t[n];
746  readMemory(GFCNT0START, tmp_f, n, props, status);
747  for(i = 0; i < nperiod; i++)
748  {
749  frames[i] = tmp_f[(i + period_start + 1) % n];
750  }
751  delete[] tmp_f;
752 // not needed now
753 // for(i=0; i<nperiod; i++)
754 // {
755 // frames[i] += (seq * req_frames[i]);
756 // }
757 // delete[] req_frames;
758  return status.result();
759 }
760 
761 // in microseconds
762 template <class EnvPeriodPolicy>
764 {
765  if ((delay >> 18) != 0)
766  {
767  status.add(FAC_ENVCARD, SEV_ERROR, ERRTYPE_INVCARD, "Period output delay too big (> 18 bits wide)");
768  }
769  return writeRegister(PEROUTDEL, delay, status);
770 }
771 
772 //int EnvPeriodCard<EnvPeriodPolicy>::startDataCollection(DAEstatus& status)
773 //{
774 // return setRegisterBits(MAT_1, (1 << 4), true, status);
775 //}
776 
777 //int EnvPeriodCard<EnvPeriodPolicy>::stopDataCollection(DAEstatus& status)
778 //{
779 // return clearRegisterBits(MAT_1, (1 << 4), status);
780 //}
781 
782 
783 
785 // environment card
787 
788 template <class EnvPeriodPolicy>
790 {
791  return setRegisterBits(RVETO, mask, preserve, status);
792 }
793 
794 template <class EnvPeriodPolicy>
796 {
797  return clearRegisterBits(RVETO, mask, status);
798 }
799 
800 template <class EnvPeriodPolicy>
802 {
803  return setRegisterBits(RCONTROL, mask, preserve, status);
804 }
805 
806 template <class EnvPeriodPolicy>
808 {
809  return clearRegisterBits(RCONTROL, mask, status);
810 }
811 
812 template <class EnvPeriodPolicy>
814 {
815  return setAndClearRegisterBits(RCONTROL, mask, preserve, status);
816 }
817 
818 template <class EnvPeriodPolicy>
820 {
821  resetRunController(status);
822  syncFrameTimer(status);
823  return setRunControlBits(RCSTART, true, status);
824 }
825 
826 template <class EnvPeriodPolicy>
828 {
829  clearRunControlBits(RCSTART, status);
830  return resetRunController(status);
831 }
832 
833 template <class EnvPeriodPolicy>
835 {
836 // clearSMPVetoedFrames(status);
837 // clearExternalVetoedFrames(status);
838 // clearFIFOVetoedFrames(status);
839  return setAndClearRegisterBits(RCONTROL, RCFCLEAR | RCPCLEAR, true, status);
840 }
841 
842 template <class EnvPeriodPolicy>
844 {
845  return setAndClearRegisterBits(RCONTROL, RCPCLEAR, true, status);
846 }
847 
848 template <class EnvPeriodPolicy>
850 {
851  isisU32_t value = 0;
852  readRegister(RCONTROL, &value, status);
853  switch(value & RCFSSEL)
854  {
855  case 0:
856  return FrameSyncInternalTest;
857  break;
858  case RCFSSMP:
859  return FrameSyncSMP;
860  break;
861  case RCFSTOF:
862  return FrameSyncISIS;
863  break;
864  case RCFSTOF1P:
866  break;
867  case RCFSMUONCK:
868  return FrameSyncMuonCerenkov;
869  break;
870  case RCFSMUONMS:
871  return FrameSyncMuonMS;
872  break;
873  default:
874  break;
875  }
876  status.addVa(FAC_DAE, SEV_ERROR, ERRTYPE_OUTOFMEM, "Invalid frame sync type %d\n", value & RCFSSEL);
877  return FrameSyncInternalTest;
878 }
879 
880 template <class EnvPeriodPolicy>
882 {
883  int stat = clearRunControlBits(RCFSSEL, status); // clear all FS bits first (sets to test clock)
884  disableMSMode(status);
885  switch(fs)
886  {
888  return stat;
889  break;
890 
891  case FrameSyncISIS:
892  return setRunControlBits(RCFSTOF, true, status);
893  break;
894 
896  return setRunControlBits(RCFSTOF1P, true, status);
897  break;
898 
899  case FrameSyncSMP:
900  return setRunControlBits(RCFSSMP, true, status);
901  break;
902 
904  return setRunControlBits(RCFSMUONCK, true, status);
905  break;
906 
907  case FrameSyncMuonMS:
908  enableMSMode(status);
909  return setRunControlBits(RCFSMUONMS, true, status);
910  break;
911 
912  default:
913  break;
914  }
915  status.addVa(FAC_DAE, SEV_ERROR, ERRTYPE_OUTOFMEM, "Invalid frame sync type %d\n", fs);
916  return DAEstatus::Failure;
917 }
918 
919 template <class EnvPeriodPolicy>
921 {
922  if (pulse == 0) // first
923  {
924  return clearRunControlBits(RCFSSCH2, status);
925  }
926  else if (pulse == 1) // second
927  {
928  return setRunControlBits(RCFSSCH2, true, status);
929  }
930  else
931  {
932  status.addWarningVa(FAC_DAE, "Invalid muon pulse number %d\n", pulse);
933  return DAEstatus::Failure;
934  }
935 }
936 
937 template <class EnvPeriodPolicy>
939 {
940  isisU32_t value;
941  readRegister(RCONTROL, &value, status);
942  if (value & RCSTART)
943  {
944  return true;
945  }
946  else
947  {
948  return false;
949  }
950 }
951 
952 template <class EnvPeriodPolicy>
954 {
955  return readRegister(FCOUNTR, value, status);
956 }
957 
958 template <class EnvPeriodPolicy>
960 {
961 // if in muon MSM
962  if (checkOptions(MSMode))
963  {
964  return readRegister(SCHPULSE, value, status);
965  }
966  else
967  {
968  return readRegister(FCOUNTG, value, status);
969  }
970 }
971 
972 template <class EnvPeriodPolicy>
974 {
975  readRegister(PCOUNTR0, value, status);
976  return 0;
977 }
978 
979 template <class EnvPeriodPolicy>
981 {
982  readRegister(PCOUNTR1, value, status);
983  return 0;
984 }
985 
986 template <class EnvPeriodPolicy>
988 {
989  isisU32_t value0 = 0, value1 = 0;
990  readRegister(PCOUNTR0, &value0, status);
991  readRegister(PCOUNTR1, &value1, status);
992  *value = (isisU64_t)value0 | ((isisU64_t)value1 << 32);
993  return 0;
994 }
995 
996 template <class EnvPeriodPolicy>
998 {
999  readRegister(PCOUNTG0, value, status);
1000  return 0;
1001 }
1002 
1003 template <class EnvPeriodPolicy>
1005 {
1006  readRegister(PCOUNTG1, value, status);
1007  return 0;
1008 }
1009 
1010 template <class EnvPeriodPolicy>
1012 {
1013  isisU32_t value0 = 0, value1 = 0;
1014  readRegister(PCOUNTG0, &value0, status);
1015  readRegister(PCOUNTG1, &value1, status);
1016  *value = (isisU64_t)value0 | ((isisU64_t)value1 << 32);
1017  return 0;
1018 }
1019 
1020 template <class EnvPeriodPolicy>
1022 {
1023  return setAndClearRunControlBits(RCRESET, true, status);
1024 }
1025 
1026 template <class EnvPeriodPolicy>
1028 {
1029  return setVetoRegisterBits(RVSMP, true, status);
1030 }
1031 
1032 template <class EnvPeriodPolicy>
1034 {
1035  switch(veto_number)
1036  {
1037  case 0:
1038  return setVetoRegisterBits(RVEXT0, true, status);
1039  break;
1040  case 1:
1041  return setVetoRegisterBits(RVEXT1, true, status);
1042  break;
1043  case 2:
1044  return setVetoRegisterBits(RVEXT2, true, status);
1045  break;
1046  case 3:
1047  return setVetoRegisterBits(RVEXT3, true, status);
1048  break;
1049  default:
1050  status.addWarningVa(FAC_DAE, "Attempting to enable invalid veto number %d", veto_number);
1051  break;
1052  }
1053  return DAEstatus::Success;
1054 }
1055 
1056 template <class EnvPeriodPolicy>
1058 {
1059  return setVetoRegisterBits(RVINT, true, status);
1060 }
1061 
1062 template <class EnvPeriodPolicy>
1064 {
1065  return setVetoRegisterBits(RVFIFO, true, status);
1066 }
1067 
1068 template <class EnvPeriodPolicy>
1069 int EnvPeriodCard<EnvPeriodPolicy>::enableFermiChopperVeto(int chopper_number, int delay, int width, DAEstatus& status)
1070 {
1071  return enableFChopperVeto(chopper_number, delay, width, status);
1072 }
1073 
1074 template <class EnvPeriodPolicy>
1076 {
1077  return setVetoRegisterBits(RVTS2P, true, status);
1078 }
1079 
1080 template <class EnvPeriodPolicy>
1082 {
1083  return setVetoRegisterBits(RVHZ50, true, status);
1084 }
1085 
1086 template <class EnvPeriodPolicy>
1088 {
1089  return clearVetoRegisterBits(RVSMP, status);
1090 }
1091 
1092 template <class EnvPeriodPolicy>
1094 {
1095  switch(veto_number)
1096  {
1097  case 0:
1098  return clearVetoRegisterBits(RVEXT0, status);
1099  break;
1100  case 1:
1101  return clearVetoRegisterBits(RVEXT1, status);
1102  break;
1103  case 2:
1104  return clearVetoRegisterBits(RVEXT2, status);
1105  break;
1106  case 3:
1107  return clearVetoRegisterBits(RVEXT3, status);
1108  break;
1109  default:
1110  status.addWarningVa(FAC_DAE, "Attempting to disable invalid veto number %d", veto_number);
1111  break;
1112  }
1113  return DAEstatus::Success;
1114 }
1115 
1116 template <class EnvPeriodPolicy>
1118 {
1119  return clearVetoRegisterBits(RVINT, status);
1120 }
1121 
1122 template <class EnvPeriodPolicy>
1124 {
1125  return clearVetoRegisterBits(RVFIFO, status);
1126 }
1127 
1128 template <class EnvPeriodPolicy>
1130 {
1131  return processFermiChopperVeto(chopper_number, boost::bind(&EnvPeriodCard<EnvPeriodPolicy>::clearVetoRegisterBits, this, _1, _2), status);
1132 }
1133 
1134 //int EnvPeriodCard<EnvPeriodPolicy>::processFermiChopperVeto(int chopper_number, int (EnvPeriodCard<EnvPeriodPolicy>::*func)(isisU32_t, DAEstatus&), DAEstatus& status)
1135 template <class EnvPeriodPolicy>
1136 int EnvPeriodCard<EnvPeriodPolicy>::processFermiChopperVeto(int chopper_number, boost::function<int(isisU32_t, DAEstatus&)> func, DAEstatus& status)
1137 {
1138  static const isisU32_t mapping[] = { RVFCHOP0, RVFCHOP1, RVFCHOP2, RVFCHOP3 };
1139  if ( chopper_number >= 0 && chopper_number < array_length(mapping) )
1140  {
1141  return func(mapping[chopper_number], status);
1142  }
1143  else
1144  {
1145  status.addWarningVa(FAC_DAE, "Attempting to process invalid fermi chopper number %d", chopper_number);
1146  }
1147  return DAEstatus::Success;
1148 }
1149 
1150 template <class EnvPeriodPolicy>
1152 {
1153  return clearVetoRegisterBits(RVTS2P, status);
1154 }
1155 
1156 template <class EnvPeriodPolicy>
1158 {
1159  return clearVetoRegisterBits(RVHZ50, status);
1160 }
1161 
1162 template <class EnvPeriodPolicy>
1164 {
1165  return readRegister(SMPVETFRM, value, status);
1166 }
1167 
1168 template <class EnvPeriodPolicy>
1170 {
1171 // return readRegister(EXTVETFRMTOT, value, status);
1172  switch(veto_number)
1173  {
1174  case 0:
1175  return readRegister(EXT0VETFRM, value, status);
1176  break;
1177  case 1:
1178  return readRegister(EXT1VETFRM, value, status);
1179  break;
1180  case 2:
1181  return readRegister(EXT2VETFRM, value, status);
1182  break;
1183  case 3:
1184  return readRegister(EXT3VETFRM, value, status);
1185  break;
1186  default:
1187  status.addWarningVa(FAC_DAE, "Attempting to read invalid external veto number %d", veto_number);
1188  break;
1189  }
1190  return DAEstatus::Success;
1191 }
1192 
1193 template <class EnvPeriodPolicy>
1195 {
1196  return readRegister(MSMVETFRM, value, status);
1197 }
1198 
1199 template <class EnvPeriodPolicy>
1201 {
1202  return readRegister(FIFOVETFRM, value, status);
1203 }
1204 
1205 template <class EnvPeriodPolicy>
1207 {
1208  return readRegister(INTVETFRM, value, status);
1209 }
1210 
1211 
1212 template <class EnvPeriodPolicy>
1214 {
1215  static const isisU32_t mapping[] = { FC0VETFRM, FC1VETFRM, FC2VETFRM, FC3VETFRM };
1216  if ( chopper_number >=0 && chopper_number < array_length(mapping) )
1217  {
1218  return readRegister(mapping[chopper_number], value, status);
1219  }
1220  else
1221  {
1222  status.addWarningVa(FAC_DAE, "Attempting to read invalid fermi chopper number %d", chopper_number);
1223  return DAEstatus::Success;
1224  }
1225 }
1226 
1227 template <class EnvPeriodPolicy>
1229 {
1230  return readRegister(TS2PVETFRM, value, status);
1231 }
1232 
1233 template <class EnvPeriodPolicy>
1235 {
1236  return readRegister(HZ50VETFRM, value, status);
1237 }
1238 
1239 //int EnvPeriodCard<EnvPeriodPolicy>::clearSMPVetoedFrames(DAEstatus& status)
1240 //{
1241 // isisU16_t value = 0;
1242 // writeRegister(SMPVETFRM0, value, status);
1243 // writeRegister(SMPVETFRM1, value, status);
1244 // return 0;
1245 //}
1246 
1247 //int EnvPeriodCard<EnvPeriodPolicy>::clearExternalVetoedFrames(DAEstatus& status)
1248 //{
1249 // isisU16_t value = 0;
1250 // writeRegister(EXTVETFRM0, value, status);
1251 // writeRegister(EXTVETFRM1, value, status);
1252 // return 0;
1253 //}
1254 
1255 //int EnvPeriodCard<EnvPeriodPolicy>::clearFIFOVetoedFrames(DAEstatus& status)
1256 //{
1257 // isisU16_t value = 0;
1258 // writeRegister(FIFOVETFRM0, value, status);
1259 // writeRegister(FIFOVETFRM1, value, status);
1260 // return 0;
1261 //}
1262 
1263 
1264 template <class EnvPeriodPolicy>
1266 {
1267  if (value < 0)
1268  {
1269  status.add(FAC_ENVCARD, SEV_ERROR, ERRTYPE_INVCARD, "Frame sync delay cannot be negative - set to zero");
1270  value = 0;
1271  }
1272 // no longer required to be at least 1
1273 // if (value == 0)
1274 // {
1275 // value = 1;
1276 // }
1277  if ((value >> 18) != 0)
1278  {
1279  status.add(FAC_ENVCARD, SEV_ERROR, ERRTYPE_INVCARD, "Frame sync delay too big (> 18 bits wide)");
1280  }
1281  clearRunControlBits(RCFSENABLEOUT, status);
1282  setAndClearRunControlBits(RCDELFSFIFORS, true, status);
1283  writeRegister(FSDELAY, value, status);
1284  setRunControlBits(RCFSENABLEOUT, true, status);
1285  return 0;
1286 }
1287 
1288 template <class EnvPeriodPolicy>
1290 {
1291  isisU32_t fs_mask = ((1 << 18) - 1); // FS only 18 bits wide
1292  readRegister(FSDELAY, value, status);
1293  *value &= fs_mask;
1294  return 0;
1295 }
1296 
1297 template <class EnvPeriodPolicy>
1299 {
1300  return clearRunControlBits(RCPERSZEQZERO, status);
1301 }
1302 
1303 template <class EnvPeriodPolicy>
1305 {
1306  return setRunControlBits(RCPERSZEQZERO, true, status);
1307 }
1308 
1309 template <class EnvPeriodPolicy>
1311 {
1312  isisU32_t value;
1313 // need to check with Matt...
1314 // readRegister(RCONTROL, &value, status);
1315 // if (value & RCPERSZEQZERO)
1316 // {
1317 // return false;
1318 // }
1319 // else
1320 // {
1321 // return true;
1322 // }
1323  readRegister(PCREG, &value, status);
1324  if (value & PCENAB)
1325  {
1326  return true;
1327  }
1328  else
1329  {
1330  return false;
1331  }
1332 }
1333 
1334 // converion factor is
1335 //
1336 // 4e13 / 1024 * 1.602e-19 * 1e6 / 3600 = 1.738e-6
1337 //
1338 // 4e13/1024 is a calibration: 1024 for 10 bit ADC, 4e13 for full load proton reading
1339 //
1340 
1341 #define PPP_TO_UAMPH 1.738E-6
1342 
1343 template <class EnvPeriodPolicy>
1345 {
1346  float good_uamps = 0.0;
1347  isisU32_t low = 0, upper = 0;
1348  getGoodPPPLower(&low, status);
1349  getGoodPPPUpper(&upper, status);
1350  good_uamps = static_cast<float>((65536.0 * 65536.0 * upper + low) * PPP_TO_UAMPH);
1351  return good_uamps;
1352 }
1353 
1354 template <class EnvPeriodPolicy>
1356 {
1357  float raw_uamps = 0.0;
1358  isisU32_t low = 0, middle = 0, upper = 0;
1359  getRawPPPLower(&low, status);
1360  getRawPPPUpper(&upper, status);
1361  raw_uamps = static_cast<float>((65536.0 * 65536.0 * upper + low) * PPP_TO_UAMPH);
1362  return raw_uamps;
1363 }
1364 
1365 template <class EnvPeriodPolicy>
1367 {
1368  int i;
1369  isisU16_t nperiod;
1370  isisU16_t value16 = 0;
1371  m_options = 0;
1372  setOptions(NoCheckSRAM);
1373  readRegister(PCREG, &value16, status);
1374  (value16 & PCMSM) ? setOptions(MSMode) : clearOptions(MSMode);
1375  readRegister(MPLIM, &nperiod, status);
1376  isisU32_t* req_frames = new isisU32_t[nperiod];
1377  getRequestedFrames(0, nperiod, req_frames, status);
1378  bool single_frames_only = true;
1379  for(i=0; i<nperiod; i++)
1380  {
1381  if (req_frames[i] != 1)
1382  {
1383  single_frames_only = false;
1384  }
1385  }
1386  // disable workaround
1387  single_frames_only = false;
1388  (single_frames_only) ? setOptions(RotateFrameCountersRight) : clearOptions(RotateFrameCountersRight);
1389  delete[] req_frames;
1390  isisU32_t ft0;
1391  DAEstatus temp_status;
1392  if (readRegister(FRAMETIME0, &ft0, temp_status) == 1)
1393  {
1394  status.addInfo(FAC_DAE, "This card supports event mode timer");
1395  setOptions(EventModeTimer);
1396  }
1397  if (readRegister(FC0WINDLY, &ft0, temp_status) == 1)
1398  {
1399  status.addInfo(FAC_DAE, "This card supports fermi chopper veto");
1400  setOptions(FChopperVeto);
1401  }
1402  return status.result();
1403 }
1404 
1405 // delay and width in 20ns steps
1406 template <class EnvPeriodPolicy>
1407 int EnvPeriodCard<EnvPeriodPolicy>::enableFChopperVeto(int chopper_number, int delay, int width, DAEstatus& status)
1408 {
1409  static const isisU32_t delay_mapping[] = { FC0WINDLY, FC1WINDLY, FC2WINDLY, FC3WINDLY };
1410  static const isisU32_t window_mapping[] = { FC0WINWTH, FC1WINWTH, FC2WINWTH, FC3WINWTH };
1411  static const isisU32_t veto_mapping[] = { RVFCHOP0, RVFCHOP1, RVFCHOP2, RVFCHOP3 };
1412 
1414  {
1415  writeRegister(delay_mapping[chopper_number], delay, status);
1416  writeRegister(window_mapping[chopper_number], width, status);
1417  status.addInfoVa(FAC_DAE, "Fermi chopper %d setting delay,width (us) = %f,%f\n", chopper_number, delay / 50.0, width / 50.0);
1418  return setVetoRegisterBits(veto_mapping[chopper_number], true, status);
1419  }
1420  else
1421  {
1422  status.add(FAC_DAE, SEV_ERROR, ERRTYPE_OUTOFMEM, "Fermi Chopper Veto Not Available");
1423  return DAEstatus::Failure;
1424  }
1425 }
1426 
1427 template <class EnvPeriodPolicy>
1429 {
1430  return disableFermiChopperVeto(chopper_number, status);
1431 }
1432 
1433 template <class EnvPeriodPolicy>
1435 {
1436  return getFermiChopperVetoedFrames(chopper_number, value, status);
1437 }
1438 
1439 template <class EnvPeriodPolicy>
1441 {
1442  float raw_uamps = 0.0;
1443  isisU32_t low = 0, middle = 0, upper = 0;
1444  getRawPPPLowerPeriod(period, &low, status);
1445  getRawPPPUpperPeriod(period, &upper, status);
1446  raw_uamps = static_cast<float>((65536.0 * 65536.0 * upper + low) * PPP_TO_UAMPH);
1447  return raw_uamps;
1448 }
1449 
1450 template <class EnvPeriodPolicy>
1452 {
1453  float good_uamps = 0.0;
1454  isisU32_t low = 0, upper = 0;
1455  getGoodPPPLowerPeriod(period, &low, status);
1456  getGoodPPPUpperPeriod(period, &upper, status);
1457  good_uamps = static_cast<float>((65536.0 * 65536.0 * upper + low) * PPP_TO_UAMPH);
1458  return good_uamps;
1459 }
1460 
1461 template <class EnvPeriodPolicy>
1463 {
1465  EnvPeriodPolicy::ppp_memory_t val;
1466  int stat = readMemory(RPCNT0START + sizeof(val)*period, &val, 1, props, status);
1467  *value = static_cast<isisU32_t>(val);
1468  return stat;
1469 }
1470 
1471 template <class EnvPeriodPolicy>
1473 {
1474  *value = 0;
1475 #if 0
1476  int stat = readMemory(RPCNT1START + 4*period, value, 1, false, false, status); // not valid for dae3
1477  (*value) &= 0xffff; // only 16 bits valid
1478  return stat;
1479 #else
1480  return DAEstatus::Success;
1481 #endif
1482 }
1483 
1484 template <class EnvPeriodPolicy>
1486 {
1487  EnvPeriodPolicy::ppp_memory_t val;
1489  int stat = readMemory(GPCNT0START + sizeof(val)*period, &val, 1, props, status);
1490  *value = static_cast<isisU32_t>(val);
1491  return stat;
1492 }
1493 
1494 template <class EnvPeriodPolicy>
1496 {
1497  *value = 0;
1498 #if 0
1499  int stat = readMemory(GPCNT1START + 4*period, value, 1, false, false, status);
1500  (*value) &= 0xffff; // only 16 bits valid
1501  return stat;
1502 #else
1503  return DAEstatus::Success;
1504 #endif
1505 }
1506 
1507 
1508 // sync time to current computer time
1509 // this counter runs at 20ns, FILETIME is in 100ns increments
1510 // the counter is large enough to hold 5 * filetime
1511 template <class EnvPeriodPolicy>
1513 {
1514  if (!checkOptions(EventModeTimer))
1515  {
1516  return DAEstatus::Success;
1517  }
1518  FILETIME filetime;
1519  m_vme->lockInterface(0, status); // get exclusive access to Visa/DAE
1520  ThreadPriorityRaiser thread_prio; // raise thread priority until end of function
1521  // see how far we are currently out
1522  status.addInfoVa(FAC_DAE, "Previous DAE time drift (icp - dae) = %f ms", frameTimerDrift(status) / 1000.0);
1523  // compute delay
1524  isisU32_t delay;
1525  computeTimeOffsetDelay(delay, status);
1526  status.addInfoVa(FAC_DAE, "Time sync delay = %f ms", delay / 50000.0);
1527  // now update DAE time
1528  DAEEventHeader::DAETime daetime;
1529  // use order zero low bits, set high bits, set low bits as counter is free runnings and may wrap
1530  writeRegister(FRAMETIME0, 0, status);
1531  ICPTimer timer;
1532  //GetSystemTimeAsFileTime(&filetime);
1533  g_icp_clock.get()->getCurrentTimeAsFiletime(filetime);
1534  DAEEventList::FILETIMEToDAETime(filetime, daetime);
1535  writeRegister(FRAMETIME1, daetime.high, status);
1536  writeRegister(FRAMETIME0, daetime.low, status);
1537  status.addInfoVa(FAC_DAE, "DAE time drift (icp - dae) = %f ms", frameTimerDrift(status) / 1000.0);
1538  m_vme->unlockInterface(status);
1539  timer.info("Time to compute and set new DAE time values", status);
1540  status.addInfoVa(FAC_DAE, "Setting new DAE time to %s", DAEEventList::DAETimeAsString(daetime).c_str());
1541  return DAEstatus::Success;
1542 }
1543 
1545 template <class EnvPeriodPolicy>
1547 {
1548  FILETIME filetime1, filetime2;
1549  m_vme->lockInterface(0, status); // get exclusive access to Visa/DAE
1550  ThreadPriorityRaiser thread_prio; // raise thread priority until end of function
1551  readFrameTimer(filetime1, status);
1552  //GetSystemTimeAsFileTime(&filetime2);
1553  g_icp_clock.get()->getCurrentTimeAsFiletime(filetime2);
1554  m_vme->unlockInterface(status);
1555  return (double)diffFileTimes(filetime1, filetime2) / 10.0; // from 100ns to us
1556 }
1557 
1558 template <class EnvPeriodPolicy>
1560 {
1561  if (!checkOptions(EventModeTimer))
1562  {
1563  memset(&ft, 0, sizeof(FILETIME));
1564  return DAEstatus::Success;
1565  }
1566  DAEEventHeader::DAETime daetime;
1567  isisU32_t ft0, ft1, temp32;
1568  readRegister(FRAMETIME0, &temp32, status);
1569  readRegister(FRAMETIME1, &ft1, status);
1570  readRegister(FRAMETIME0, &ft0, status);
1571  if (ft0 < temp32) // did ft0 wrap during the read? If so read again
1572  {
1573  readRegister(FRAMETIME1, &ft1, status);
1574  readRegister(FRAMETIME0, &ft0, status);
1575  }
1576  daetime.low = ft0;
1577  daetime.high = ft1;
1578  DAEEventList::DAETimeToFILETIME(daetime, ft);
1579  return DAEstatus::Success;
1580 }
1581 
1583 template <class EnvPeriodPolicy>
1585 {
1586  writeRegister(FRAMETIME0, 0, status);
1587  readRegister(FRAMETIME0, &delay, status);
1588  return DAEstatus::Success;
1589 }
1590 
1591 template <class EnvPeriodPolicy>
1593 {
1594  return setRunControlBits(RCEVENTMODE, true, status);
1595 }
1596 
1597 template <class EnvPeriodPolicy>
1599 {
1600  return clearRunControlBits(RCEVENTMODE, status);
1601 }
1602 
1626 template <class EnvPeriodPolicy>
1628 {
1630  LOGSTR_INFORMATION("Resetting card state");
1631 // uint32_t check_mask0 = (checkOptions(NoCheckSRAM) ? 0x0 : 0xffffffff);
1632 // uint32_t check_mask1 = (checkOptions(NoCheckSRAM) ? 0x0 : 0x0000ffff);
1633  uint32_t check_mask0 = 0x0;
1634  uint32_t check_mask1 = 0x0;
1635 
1636  writeRegister(FSDELAY, 0x1, status);
1637  writeRegister(FC0WINDLY, 0xfa0, status);
1638  writeRegister(FC0WINWTH, 0x5dc, status);
1639 
1640 // mantalk 0 0 300 0 6
1641  writeRegister(MPCNT, 0x0, status);
1642  writeRegister(MPLIM, 0x0, status);
1643  writeRegister(PSCNT, 0x0, status);
1644  writeRegister(PSLR, 0x0, status);
1645  writeRegister(PERINCTOT, 0x0, status);
1646  writeRegister(PEROUTDEL, 0x0, status);
1647 
1648  writeRegister(LOOKTAR, 0x0, status);
1649  writeRegister(RVETO, 0x0, status);
1650  writeRegister(RCONTROL, 0xc006, status);
1651  writeRegister(PCREG, 0x8000, status);
1652  writeRegister(RCONTROL, 0x100008, status);
1653  writeRegister(PCREG, 0x0, status);
1654 
1655 // mantalk 0 0 80000 0 10000
1656  zeroMemory<isisU32_t>(PERLUTSTART, PERLUTSIZE, check_mask0, props, status); // 0x10000 = 65536
1657 // mantalk 0 0 c0000 0 4000
1658  zeroMemory<isisU32_t>(OUTLUTSTART, OUTLUTSIZE, check_mask0, props, status); // 0x4000 = 16384
1659 // mantalk 0 0 100000 0 10000
1660  zeroMemory<isisU32_t>(RFCNT0START, RFCNT0SIZE, check_mask0, props, status); // 0x10000 = 65536
1661 // mantalk 0 0 140000 0 10000
1662 // zeroMemory(RPCNT1START, RPCNT1SIZE, check_mask1, props, status); // 0x10000 = 65536 // not valid for dae3
1663  // zeroPeriodFrameCounters(status);
1664  // zeroPeriodProtonCounters(status);
1665  // zeroPeriodExtraCounters(status);
1666 
1667  return ISISVME::Success;
1668 }
1669 
1671  { "FIFO Veto", RVFIFO, FIFOVETFRM, false },
1672  { "SMP (chopper) Veto", RVSMP, SMPVETFRM, false },
1673  { "Internal Veto", RVINT, INTVETFRM, true },
1674  { "Fermi Chopper0 Veto", RVFCHOP0, FC0VETFRM, false },
1675 // { "Fermi Chopper1 Veto", RVFCHOP1, FC1VETFRM, false },
1676 // { "Fermi Chopper2 Veto", RVFCHOP2, FC2VETFRM, false },
1677 // { "Fermi Chopper3 Veto", RVFCHOP3, FC3VETFRM, false },
1678  { "TS2 Pulse Veto", RVTS2P, TS2PVETFRM, false },
1679  { "ISIS 50 Hz Veto", RVHZ50, HZ50VETFRM, false },
1680  { "MS Mode Veto", RVMSM, MSMVETFRM, true },
1681  { "External Veto 0", RVEXT0, EXT0VETFRM, false },
1682  { "External Veto 1", RVEXT1, EXT1VETFRM, false },
1683  { "External Veto 2", RVEXT2, EXT2VETFRM, false },
1684  { "External Veto 3", RVEXT3, EXT3VETFRM, false },
1685  { NULL, 0, 0, false } // must end with NULL name
1686 };
1687 
1689  { "FIFO Veto", RVFIFO, FIFOVETFRM, false },
1690  { "SMP (chopper) Veto", RVSMP, SMPVETFRM, false },
1691  { "Internal Veto", RVINT, INTVETFRM, true },
1692  { "Fermi Chopper0 Veto", RVFCHOP0, FC0VETFRM, false },
1693 // { "Fermi Chopper1 Veto", RVFCHOP1, FC1VETFRM, false },
1694 // { "Fermi Chopper2 Veto", RVFCHOP2, FC2VETFRM, false },
1695 // { "Fermi Chopper3 Veto", RVFCHOP3, FC3VETFRM, false },
1696  { "TS2 Pulse Veto", RVTS2P, TS2PVETFRM, false },
1697  { "ISIS 50 Hz Veto", RVHZ50, HZ50VETFRM, false },
1698  { "MS Mode Veto", RVMSM, MSMVETFRM, true },
1699  { "External Veto 0", RVEXT0, EXT0VETFRM, false },
1700  { "External Veto 1", RVEXT1, EXT1VETFRM, false },
1701  { "External Veto 2", RVEXT2, EXT2VETFRM, false },
1702  { "External Veto 3", RVEXT3, EXT3VETFRM, false },
1703  { NULL, 0, 0, false } // must end with NULL name
1704 };
1705 
1706 template class EnvPeriodCard<DAE2EnvPeriodPolicy>;
1707 template class EnvPeriodCard<DAE3EnvPeriodPolicy>;
1708 
int enableEventMode(DAEstatus &status)
int processFermiChopperVeto(int chopper_number, boost::function< int(isisU32_t, DAEstatus &)> func, DAEstatus &status)
int disablePeriodMode(DAEstatus &status)
int setVetoRegisterBits(isisU32_t mask, bool preserve, DAEstatus &status)
uint32_t TransferProps
combination of TransferProp values
Definition: isisvme.h:16
int getPeriodGoodFrames(int period, isisU32_t *frames, DAEstatus &status)
#define FAC_DAE
LONGLONG diffFileTimes(const FILETIME &start, const FILETIME &finish)
finish - start, returned in 100ns units
Definition: icputils.cpp:630
#define ERRTYPE_OUTOFMEM
int disableSMPVeto(DAEstatus &status)
int endRunAfterSequenceCompletes(DAEstatus &status)
#define RFCNT0START
Definition: period_card.h:31
int addVa(int facility, int severity, int errtype, const char *format,...)
Definition: DAEstatus.cpp:54
int enableISIS50HzVeto(DAEstatus &status)
int enableExternalVeto(int veto_number, DAEstatus &status)
int disableTS2PulseVeto(DAEstatus &status)
#define PPP_TO_UAMPH
#define RFCNT0SIZE
Definition: period_card.h:36
#define PCMULENAB
Definition: period_card.h:54
int getSMPVetoedFrames(isisU32_t *value, DAEstatus &status)
static const period_modes mode_list[]
int whichVeto(std::ostream &os, DAEstatus &status)
keeps a static variable count of last values, should be safe as only one environment card ...
int clearVetoRegisterBits(isisU32_t mask, DAEstatus &status)
int getRawPPPUpperPeriod(int period, isisU32_t *value, DAEstatus &status)
int resetRunController(DAEstatus &status)
#define PCENAB
Definition: period_card.h:52
int disableDelayedStart(DAEstatus &status)
int getInternalVetoedFrames(isisU32_t *value, DAEstatus &status)
int disableExternalVeto(int veto_number, DAEstatus &status)
#define GFCNT0START
Definition: period_card.h:33
int clearPeriodControlBits(isisU32_t mask, DAEstatus &status)
unsigned long isisU32_t
Definition: isisvme_types.h:8
int readPERLUT(isisU16_t *dwell_flags, isisU16_t *frames, int nperiod, DAEstatus &status)
double frameTimerDrift(DAEstatus &status)
return drift in microseconds, icp - dae
int getRawPPPLowerPeriod(int period, isisU32_t *value, DAEstatus &status)
static const int Failure
Definition: DAEstatus.h:141
int getPeriodRawFrames(int period, isisU32_t *frames, DAEstatus &status)
int enableFermiChopperVeto(int chopper_number, int delay, int width, DAEstatus &status)
int add(DAEstatus &dstatus, bool clear)
Definition: DAEstatus.cpp:131
int getGoodFrames(int period_start, int nperiod, isisU32_t frames[], DAEstatus &status)
int setMuonPulse(int pulse, DAEstatus &status)
int getRawFrames(int period_start, int nperiod, isisU32_t frames[], DAEstatus &status)
int clearPeriodCounters(DAEstatus &status)
int disableMSMode(DAEstatus &status)
#define MAX_NUM_PERIODS
Definition: period_card.h:6
int enableMSMode(DAEstatus &status)
bool usingHardwarePeriods(DAEstatus &status)
int lookupFinished(DAEstatus &status)
static const int Success
Definition: DAEstatus.h:140
int getRawPPPLower(isisU32_t *value, DAEstatus &status)
int getPeriodRequestedFrames(int period, isisU32_t *frames, DAEstatus &status)
int getGoodPPPLower(isisU32_t *value, DAEstatus &status)
int disableInternalVeto(DAEstatus &status)
virtual void printStatus(std::ostream &os, DAEstatus &dstatus)
Definition: dae2_card.cpp:453
#define OUTLUTSTART
Definition: period_card.h:28
int getRawPPP(isisU64_t *value, DAEstatus &status)
int getExternalVetoedFrames(int veto_number, isisU32_t *value, DAEstatus &status)
float getGoodUAmpHoursPeriod(int period, DAEstatus &status)
int disableFChopperVeto(int chopper_number, DAEstatus &status)
int enableFIFOVeto(DAEstatus &status)
size_t array_length(const T &)
calculate number of elements in a fixed array e.g. int something[10] ot int s[] = { &quot;a&quot;...
Definition: icputils.h:468
int updateOptions(DAEstatus &status)
#define LOGSTR_WARNING(__arg)
Definition: IsisBase.h:92
void printStatus(std::ostream &os, DAEstatus &status)
FrameSync getFrameSync(DAEstatus &status)
int disableFermiChopperVeto(int chopper_number, DAEstatus &status)
float getRawUAmpHoursPeriod(int period, DAEstatus &status)
const char * unset
static void DAETimeToFILETIME(const DAEEventHeader::DAETime &daetime, FILETIME &filetime)
Definition: dae_events.cpp:215
#define TARPERLUT
Definition: period_card.h:42
int getGoodPPPUpperPeriod(int period, isisU32_t *value, DAEstatus &status)
int disableHardwarePeriods(DAEstatus &status)
bool isMultipleSequenceComplete(DAEstatus &status)
int zeroPeriodFrameCounters(DAEstatus &status)
int getMSModeVetoedFrames(isisU32_t *value, DAEstatus &status)
EnvPeriodCard(int position, ISISVME *vme, DAEstatus &status)
int getGoodPPPLowerPeriod(int period, isisU32_t *value, DAEstatus &status)
int setRunControlBits(isisU32_t mask, bool preserve, DAEstatus &status)
#define TAROUTLUT
Definition: period_card.h:43
int syncFrameTimer(DAEstatus &status)
int enableTS2PulseVeto(DAEstatus &status)
int zeroPeriodProtonCounters(DAEstatus &status)
#define SEV_ERROR
int setFrameSyncDelay(isisU32_t value, DAEstatus &status)
int disableEventMode(DAEstatus &status)
int resetPeriodCard(DAEstatus &status)
int setMultiplePeriodSequenceMode(int nseq, DAEstatus &status)
#define PSLR
Definition: period_card.h:13
#define PCEXTENAB
Definition: period_card.h:53
int readOUTLUT(isisU32_t *outputs, int nperiod, DAEstatus &status)
#define LOGSTR_INFORMATION(__arg)
Definition: IsisBase.h:78
int programPERLUT(isisU16_t *dwell_flags, isisU16_t *frames, int nperiod, DAEstatus &status)
bool isRunEndedAndSequenceComplete(DAEstatus &status)
#define PCENDSEQCOMP
Definition: period_card.h:51
unsigned short isisU16_t
Definition: isisvme_types.h:7
do not check SRAM areas after zeroing - workaround for broken cards
int setNumberOfPeriods(isisU16_t n, DAEstatus &status)
int setPeriodControlBits(isisU32_t mask, bool preserve, DAEstatus &status)
int getCurrentPeriodSequence(DAEstatus &status)
FrameSync
Definition: isiscrpt_types.h:5
int getFrameSyncDelay(isisU32_t *value, DAEstatus &status)
int lookupAccessOUTLUT(DAEstatus &status)
#define GFCNT0SIZE
Definition: period_card.h:38
float getRawUAmpHours(DAEstatus &status)
int enableDelayedStart(DAEstatus &status)
double info(const char *title, std::ostream &os, bool add_nl=true)
Definition: icptimer.h:83
#define PCENDAFTER
Definition: period_card.h:49
#define OUTLUTSIZE
Definition: period_card.h:29
static std::string DAETimeAsString(const DAEEventHeader::DAETime &daetime)
return as ISO8601 format string
Definition: dae_events.cpp:266
Poco::SingletonHolder< ICPClock > g_icp_clock
Definition: icputils.cpp:5
#define PERLUTSIZE
Definition: period_card.h:25
int enableInternalVeto(DAEstatus &status)
#define PCREG
Definition: period_card.h:21
int addWarningVa(int facility, const char *format,...)
Definition: DAEstatus.cpp:106
bool isRunning(DAEstatus &status)
int enableFChopperVeto(int chopper_number, int delay, int width, DAEstatus &status)
int startRun(DAEstatus &status)
ULONG64 isisU64_t
Definition: isisvme_types.h:10
#define RPCNT0START
Definition: period_card.h:35
static const veto_detail veto_details[]
int enablePeriodMode(bool external_mode, DAEstatus &status)
static void FILETIMEToDAETime(const FILETIME &filetime, DAEEventHeader::DAETime &daetime)
Definition: dae_events.cpp:255
#define GPCNT0START
Definition: period_card.h:37
#define PERLUTSTART
Definition: period_card.h:24
int getCurrentPeriodNumber(DAEstatus &status)
int setPeriodOutputDelay(isisU32_t delay, DAEstatus &status)
int getGoodPPPUpper(isisU32_t *value, DAEstatus &status)
int getGoodPPP(isisU64_t *value, DAEstatus &status)
#define PCRESET
Definition: period_card.h:61
int getFChopperVetoedFrames(int chopper_number, isisU32_t *value, DAEstatus &status)
int setFrameSync(FrameSync fs, DAEstatus &status)
#define ERRTYPE_INVCARD
int stopRun(DAEstatus &status)
int printVetoDetails(std::ostream &os, DAEstatus &status)
int computeTimeOffsetDelay(isisU32_t &delay, DAEstatus &status)
compute the delay in reading or writing a value in DAE time units (20ns)
#define FAC_ENVCARD
#define PCMULCOMP
Definition: period_card.h:55
void setLoggerName(const std::string &logger_name)
Definition: IsisBase.h:17
int setAndClearPeriodControlBits(isisU32_t mask, bool preserve, DAEstatus &status)
int getISIS50HzVetoedFrames(isisU32_t *value, DAEstatus &status)
float getGoodUAmpHours(DAEstatus &status)
int disableFIFOVeto(DAEstatus &status)
int setSinglePeriodSequenceMode(DAEstatus &status)
int clearRunControlBits(isisU32_t mask, DAEstatus &status)
int disableISIS50HzVeto(DAEstatus &status)
int ClearFramesAndPPP(DAEstatus &status)
int lookupAccessPERLUT(DAEstatus &status)
#define MPCNT
Definition: period_card.h:10
int addInfo(int facility, const std::string &text)
Definition: DAEstatus.cpp:86
int getFermiChopperVetoedFrames(int chopper_number, isisU32_t *value, DAEstatus &status)
void abortSequenceCompleteWait(DAEstatus &status)
int clearPPP(DAEstatus &status)
#define LOOKTAR
Definition: period_card.h:20
int getNumberOfPeriods(DAEstatus &status)
bool checkOptions(EnvPCOptions opts)
int result()
Definition: DAEstatus.h:144
#define PSCNT
Definition: period_card.h:12
int getFIFOVetoedFrames(isisU32_t *value, DAEstatus &status)
int getRawPPPUpper(isisU32_t *value, DAEstatus &status)
int enableHardwarePeriods(DAEstatus &status)
int addInfoVa(int facility, const char *format,...)
Definition: DAEstatus.cpp:91
int getTS2PulseVetoedFrames(isisU32_t *value, DAEstatus &status)
#define PCCLRPC
Definition: period_card.h:60
int getRequestedFrames(int period_start, int nperiod, isisU32_t frames[], DAEstatus &status)
int zeroPeriodExtraCounters(DAEstatus &status)
int readFrameTimer(FILETIME &ft, DAEstatus &status)
int programOUTLUT(isisU32_t *outputs, int nperiod, DAEstatus &status)
#define MPLIM
Definition: period_card.h:11
const char * set
bool isEndRunAfterSequenceCompletesInProgress(DAEstatus &status)
static const veto_detail veto_details[]
virtual int resetCardState(DAEstatus &status)
int enableSMPVeto(DAEstatus &status)
int setAndClearRunControlBits(isisU32_t mask, bool preserve, DAEstatus &status)
bool inDwellPeriod(DAEstatus &status)