tic  130
tina.hxx
Go to the documentation of this file.
1 #ifndef _TINA_TINA_HXX
2 #define _TINA_TINA_HXX
3 
4 #include <assert.h>
5 #include <list>
6 #include <deque>
7 #include <algorithm>
8 #include "cplRaw/flags.hxx"
9 #include "cplRaw/dbg.hxx"
10 #include "umi/umi_task.hxx"
11 #include "umipro_tina.hxx"
12 #include "tina/tico_pub.hxx"
13 #include <stdint.h>
14 #undef min
15 #undef max
16 
24 namespace INdepTina100 {
25  namespace Umi=INdepUmi100 ;
26 
27 
28 
29  typedef double Freq;
30  typedef Umi::Time Time;
31  typedef std::pair<Counter, Timer> Edge;
32  typedef std::pair<Timer, Timer> Pulse; /* high / low */
33 
34 
38  class TinaMode:public Failable, public DebugLog {
39  const int _cFifo; /* count of fifos/capture_units used (1-2) */
40  const TiCore *_ptc;
41  protected:
42  TinaConfig _tc; /* server config request */
43  unsigned _cBlock; /* sample count maximum, 0=unlimited */
44  Timer _tmTmo;
45  Timer _tmLim;
46  union {
47  /* current epoch per channel */
48  Timer _tmEpoch;
49  Timer _mptmEpoch[2];
50  };
51  private:
52  Umi::Time _tiTmo;
53  protected:
54 
55  int timeout(Timer tmCur, bool fReset);
56 
57  const TiCore *ptc() const { return _ptc; } /* set by init() */
58 
59 
60  public:
61  const TinaConfig &tc() { return _tc; }
62 
63 
64 
65  unsigned cBlock() const { return _cBlock; }
66  int cFifo() const { return _cFifo; }
67  int cCapt() const { return _cFifo; } /* capture units required */
68  Umi::Time tiTmo() { return _tiTmo; }
69 
70  /* per ECU flags */
71 
72  bool fEdgeRise(int i) const { return i; } /* 1 = rising, 0= falling */
73  bool fModeFilt(int i) const { return 0; } /* 1 = filtered, 0 = raw */
74 
75  virtual void sample( std::streambuf *psb, int iFifo ) = 0;
76  virtual void init( const TiCore *ptc );
77  virtual bool isDone() const =0;
78  virtual unsigned cSamp() const =0;
79 
80  TinaMode(int cFifo, unsigned cBlock, const Umi::Time &tiTmo);
81  TinaMode():_cFifo(0) { assert(0); }
82  virtual ~TinaMode();
83  };
84 
88  class ModeAvg : public TinaMode {
89  /* constructor arguments */
90  unsigned _cScale; /* requested total scale */
91  unsigned _cRep; /* scale (software scaler) */
92  unsigned _iRep;
93 
94  Timer _tiPrev;
95  std::deque<Timer> _dqTimes;
96 
97  private:
98  void init( const TiCore *ptc );
99 
101  void sample( std::streambuf *psb, int iFifo );
102 
103  public:
107  bool isDone() const { return cBlock() && _dqTimes.size() > cBlock(); }
108 
112  unsigned cMeas() const { return _dqTimes.size() > 1 ? _dqTimes.size() -1 : 0; }
113  unsigned cSamp() const { return cMeas() ; }
114 
121  double rdFreq();
122  double rdPeriod();
128  void clear();
129 
130 
137  ModeAvg(unsigned cAverage, unsigned cBlock=1, const Umi::Time &tiTmo=Umi::Time(1));
138 
143  ~ModeAvg();
144  };
145 
146 
147  class ModeDual:public TinaMode {
148  typedef std::deque<Timer> Segment; /* segment of continous events */
149  std::deque<Segment> _mpdqSeg[2];
150 
151  protected:
152 
153  std::deque<Timer>& dqTimes(int i) { return _mpdqSeg[i].back() /*._dqTimes*/; }
154  const std::deque<Timer>& dqTimes(int i) const { return _mpdqSeg[i].back()/*._dqTimes*/; }
155 
156  enum { LE=0, TE=1 }; /* leading/trailing edge */
157  const unsigned _cExtraLE; /* pulse mode needs terminating LE */
158 
159 
161  void sample( std::streambuf *psb, int iFifo );
162  void init( const TiCore *ptc );
163  //unsigned cSeg() const { return _dqSeg.size(); }
164  //unsigned cSegRq() const { return 1; }
165 
166  unsigned sizeLE() const { return dqTimes(LE).size()<_cExtraLE ? 0:dqTimes(LE).size()-_cExtraLE; }
167  unsigned sizeTE() const { return dqTimes(TE).size(); }
168  public:
169  unsigned cSamp() const { return std::min(sizeLE(), sizeTE()); }
170  bool isDone() const { return cBlock() && cSamp() >= cBlock(); }
171 
172  protected:
173  ModeDual(unsigned cSampRq, const Umi::Time &tiTmo, unsigned cExtraLE):TinaMode(2, cSampRq, tiTmo),_cExtraLE(cExtraLE) {
174  _mpdqSeg[LE].push_back(Segment());
175  _mpdqSeg[TE].push_back(Segment());
176  }
177  ~ModeDual() { }
178  };
179 
183  class ModeDelay:public ModeDual {
184  };
185 
189  class ModePulseWidth:public ModeDual {
190  int _eMode; /* 'H'=high width, 'L'=low width */
191  public:
192  double rdPulseWidth();
193 
194 
195  //Failable &setMode(int eMode) ;
196  //Failable &setTimeout(const Time &ti) ;
197  ModePulseWidth(int eMode='H', unsigned cSampRq=1, const Umi::Time &tiTmo=Umi::Time(1));
198  ~ModePulseWidth();
199  };
200 
206  class ModePulse:public ModeDual {
207  int _eMode; /* 'H'=high width, 'L'=low width */
208  std::pair<double, double> _pardPulse;
209  public:
210 
211  std::pair<double, double> pardPulse();
212  double rdFirst() const { return _pardPulse.first; }
213  double rdSecond() const { return _pardPulse.second; }
214 
215  //Failable &setMode(int eMode) ;
216  //Failable &setTimeout(const Time &ti) ;
217  ModePulse(int eMode='H', unsigned cSampRq=1, const Umi::Time &tiTmo=Umi::Time(1));
218  ~ModePulse();
219  };
220 
221 
222 
223 
229  class ModeTotalCount:public TinaMode, public std::list<Edge> {
230  int _eMode; /* R=rising, F=falling edge */
231  Counter _ctEpoch; /* event counter epochs */
232 
234  void sample( std::streambuf *psb, int iFifo );
235  void init( const TiCore *ptc );
236 
237  std::deque<Counter> _dqCounts;
238 
239  public:
240  bool isDone() const { return cBlock() && _dqCounts.size() >= cBlock(); }
241  unsigned cSamp() const { return _dqCounts.size(); }
242  Counter ctCurrent() { return begin()->first; }
243 
244  Counter count();
245 
246  int setEdge(int eMode) { return (eMode == 'R' || eMode == 'F') ? _eMode=eMode, 0 : -1 ; }
247  ModeTotalCount(int eMode='R', unsigned cSampRq=1, const Umi::Time &tiTmo=Umi::Time(1));
248  ~ModeTotalCount();
249  };
250 
251 
252  /* sequence of pulse widths */
253  class ModePulseWidthSequence:public TinaMode, public std::list<Time> {
254  };
255 
257  Time tiCurrent() { return *begin(); }
258  };
259 
260  /*
261  * Pulse Period
262  */
263 
264  /* samples of most-recent pulse seen */
265  class TimoPulsePeriodSamples:public TinaMode, public std::list<Pulse> {
266  int _eMode; /* 1=leading, -1 = trailing edge */
267  public:
268 
270  void sample( const char mpch[6] ) ;
271 
272  Failable &setMode(int eMode) ;
273  Failable &setTimeout(const Time &ti) ;
276  };
277 
278  /* sequence of pulse widths */
279  class TimoPulsePeriodSequence:public TinaMode, public std::list<Pulse> {
280  };
281 
283  Pulse puCurrent() { return *begin(); }
284  };
285 
286  /*
287  * Period/Frequency Average
288  * for increased precision, higher frequencies, higher troughput
289  */
290  class TimoFreqAvgSequence:public TinaMode, public std::list<Freq> {
291  };
292 
293  /* Start/Stop */
294  class TimoStartSglStop:public TinaMode { };
295  class TimoStartMltStop:public TinaMode { };
296 
300  class PulseLine : public Time {
301  bool _fChip;
302  public:
303  bool fChip() const { return _fChip; }
304  PulseLine(const Time &ti, bool f):Time(ti), _fChip(f) { }
305  ~PulseLine() { }
306  };
307 
308  class PulseMode:public Failable, public std::deque<PulseLine> {
309  public:
310  virtual int cPulse( ) { return size(); }
311  virtual void pulse( char mpch[6], const TiCore *ptc );
312  PulseMode();
313  ~PulseMode();
314  };
315  extern Time ti(double rd);
316 
317  class PumoFreq:public PulseMode {
318  public:
319 
320 
321  void init(double rdWidthLow, double rdWidthHigh) {
322  push_front(PulseLine(ti(rdWidthLow), 0));
323  push_front(PulseLine(ti(rdWidthHigh), 1));
324  }
325 
326  PumoFreq(double rdFreq, double rdDuty=0.5) {
327  if (rdDuty > 1.0) rdDuty=1.0;
328  if (rdDuty < 0.0) rdDuty=0.0;
329  init(rdDuty/rdFreq,(1.0-rdDuty)/rdFreq);
330  }
331 
332  //PumoFreq(double rdWidthLow, double rdWidthHigh) { init(rdWidthLow, rdWidthHigh); }
333 
334 
335 
336  ~PumoFreq() { }
337  };
338 
339 
340 
341  class TinaPulseConfigClientFunc:public Umi::TaskFunc::Func {
342  int _cnServer;
343  PulseMode *_ppm;
344  const TiCore *_ptc;
345 
346  int cnServer() const { return _cnServer; }
347 
348  public:
349  int func( int eState ) {
350  switch (eState) {
351  case 0: { /* init */
352  return setup(1, fCanput(cnServer()));
353  } break;
354  case 1: {
355  /* write data rq */
356  new(pmu(cnServer())->puc()) TinaPulseConfig();
357  while(_ppm->cPulse()) {
358  char mpch[6];
359  _ppm->pulse(mpch, _ptc);
360  for (unsigned i=0; i < 6; i++) {
361  assert(pmu(cnServer())->pup()->canput());
362  pmu(cnServer())->pup()->sputc(mpch[i]);
363  }
364  }
365  return setup(2, fCanget(cnServer()), fSendup(cnServer()));
366  } break ;
367  case 2: {
368  /* poke rp */
369  TinaResp* ptr=pTinaResp(pmd(cnServer())->puc());
370  assert(ptr);
371  ptr+=0;
372  return setup(-1, 0, fReleasedown(cnServer()));
373  } break ;
374  default: assert(0);
375  }
376  return 0;
377  }
378  TinaPulseConfigClientFunc(int cnServer, PulseMode *ppm, const TiCore *ptc):_cnServer(cnServer), _ppm(ppm), _ptc(ptc) { }
380  };
381 
382 
386  class TinaPlex:public Umi::TaskPlex, public Failable {
387  Umi::ChanUser *_pucIo;
388  Umi::Channel *_puc;
389  const TiCore *_ptc;
390 
391  bool _fRun;
392 
393  void done(Umi::Task *pta) { /* TaskUser virtual */
394  _fRun=0;
395  }
396 
397 
398 
399 
400 
401  void run(Umi::TaskFunc::Func *ptf) {
402  assert(!_fRun);
403  _fRun=1;
404 
405  TaskFunc::run(ptf);
406  sigUp(0, _puc, 0);
407  runio(_pucIo);
408  assert(!_fRun);
409  }
410 
411  public:
412 
416  int callTinaConfig(TinaMode *ptm);
417 
421  int callTinaSample(TinaMode *ptm);
422 
423  int callPulseConfig(PumoFreq *ptm) {
424  TinaPulseConfigClientFunc *ptf=new TinaPulseConfigClientFunc(0, ptm, _ptc); /* deleted by task code ! */
425  run(ptf);
426  return ptm->isGood();
427  }
428 
429 
430  TinaPlex(Umi::Channel *puc, Umi::ChanUser *pucIo):Umi::TaskPlex(puc),
431  _pucIo(pucIo),
432  _puc(puc),
433  _ptc(&tc2n5),
434  _fRun(false)
435  { }
436  };
437 
438 }
439 
440 #endif
441 
Definition: tina.hxx:282
bool isGood() const
fine
Definition: failable.hxx:40
Pulse Width.
Definition: tina.hxx:189
Failable & clear()
user clear of failed/bad state
Definition: failable.hxx:87
Definition: tina.hxx:294
Edge counts sampled on interval or external signal.
Definition: tina.hxx:229
Pulse Generator Mode.
Definition: tina.hxx:300
Definition: tina.hxx:290
Definition: tina.hxx:147
Definition: tina.hxx:308
Definition: tina.hxx:295
Definition: tina.hxx:265
Definition: tina.hxx:253
bool isDone() const
true when the requested count of measurements (defined by the cBlock constructor argument) is availab...
Definition: tina.hxx:107
Tina Protocol Plexer.
Definition: tina.hxx:386
Definition: umipro_tina.hxx:172
Frequency/Period Average measurement mode.
Definition: tina.hxx:88
namespace for the ines Timing Analyzer (Tina) interface
Definition: protocols.cxx:7
Delay A to B channel.
Definition: tina.hxx:183
Definition: tina.hxx:256
Definition: tina.hxx:317
base class for something that does have a failed/good state.
Definition: failable.hxx:13
unsigned cMeas() const
current count of measurements available for read via rdFreq(), rdPeriod()
Definition: tina.hxx:112
Definition: umipro_tina.hxx:73
Definition: tinacp.cxx:82
Definition: umipro_tina.hxx:19
Timing Analyzer Mode.
Definition: tina.hxx:38
Pulse Width REMIND: implement sampled mode (one capt per sample clock) REMIND: implement pulse mode (...
Definition: tina.hxx:206