mrfioc2  2.3.0
drvem.h
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2010 Brookhaven Science Associates, as Operator of
3 * Brookhaven National Laboratory.
4 * Copyright (c) 2015 Paul Scherrer Institute (PSI), Villigen, Switzerland
5 * mrfioc2 is distributed subject to a Software License Agreement found
6 * in file LICENSE that is included with this distribution.
7 \*************************************************************************/
8 /*
9  * Author: Michael Davidsaver <mdavidsaver@gmail.com>
10  */
11 
12 #ifndef EVRMRML_H_INC
13 #define EVRMRML_H_INC
14 
15 #include "evr/evr.h"
16 
17 #include <string>
18 #include <vector>
19 #include <set>
20 #include <list>
21 #include <map>
22 #include <utility>
23 
24 #include <dbScan.h>
25 #include <epicsTime.h>
26 #include <epicsThread.h>
27 #include <epicsMessageQueue.h>
28 #include <callback.h>
29 #include <epicsMutex.h>
30 
31 #include "drvemInput.h"
32 #include "drvemOutput.h"
33 #include "drvemPrescaler.h"
34 #include "drvemPulser.h"
35 #include "drvemCML.h"
36 #include "drvemTSBuffer.h"
37 #include "delayModule.h"
38 #include "drvemRxBuf.h"
39 #include "mrmevrseq.h"
40 #include "mrmspi.h"
41 
42 #include "mrmGpio.h"
43 #include "mrmtimesrc.h"
44 #include "mrmDataBufTx.h"
45 #include "sfp.h"
46 #include "configurationInfo.h"
47 
48 class EVRMRM;
49 
50 struct eventCode {
51  epicsUInt8 code; // constant
53 
54  // For efficiency events will only
55  // be mapped into the FIFO when this
56  // counter is non-zero.
57  size_t interested;
58 
59  epicsUInt32 last_sec;
60  epicsUInt32 last_evt;
61 
62  typedef std::set<EVRMRMTSBuffer*> tbufs_t;
63  tbufs_t tbufs;
64 
65  IOSCANPVT occured;
66 
67  typedef std::list<std::pair<EVR::eventCallback,void*> > notifiees_t;
68  notifiees_t notifiees;
69 
70  CALLBACK done_cb;
71  size_t waitingfor;
72  bool again;
73 
74  eventCode():owner(0), interested(0), last_sec(0)
75  ,last_evt(0), waitingfor(0), again(false)
76  {
77  scanIoInit(&occured);
78  // done_cb - initialized in EVRMRM::EVRMRM()
79  }
80 };
81 
86 class epicsShareClass EVRMRM : public mrf::ObjectInst<EVRMRM, EVR>,
87  public MRMSPI,
88  public TimeStampSource
89 {
91 public:
96  mutable epicsMutex evrLock;
97 
98  struct Config {
99  const char *model;
100  size_t nPul; // number of pulsers
101  size_t nPS; // number of prescalers
102  // # of outputs (Front panel, FP Universal, Rear transition module, Backplane)
103  size_t nOFP, nOFPUV, nORB, nOBack;
104  size_t nOFPDly; // # of slots== # of delay modules. Some of the FP Universals have GPIOs. Each FPUV==2 GPIO pins, 2 FPUVs in one slot = 4 GPIO pins. One dly module uses 4 GPIO pins.
105  // # of CML outputs
106  size_t nCML;
108  // # of FP inputs
109  size_t nIFP;
110  };
111 
112  EVRMRM(const std::string& n, bus_configuration& busConfig,
113  const Config *c,
114  volatile unsigned char*,epicsUInt32);
115 
116  virtual ~EVRMRM();
117 private:
118  void cleanup();
119 public:
120 
121  virtual void lock() const OVERRIDE FINAL {evrLock.lock();}
122  virtual void unlock() const OVERRIDE FINAL {evrLock.unlock();};
123 
124  virtual std::string model() const OVERRIDE FINAL;
125  epicsUInt32 fpgaFirmware();
126  formFactor getFormFactor();
127  std::string formFactorStr();
128  virtual MRFVersion version() const OVERRIDE FINAL;
129 
130 
131  virtual bool enabled() const OVERRIDE FINAL;
132  virtual void enable(bool v) OVERRIDE FINAL;
133 
134  virtual bool mappedOutputState() const OVERRIDE FINAL;
135 
136  MRMGpio* gpio();
137 
138  virtual bool specialMapped(epicsUInt32 code, epicsUInt32 func) const OVERRIDE FINAL;
139  virtual void specialSetMap(epicsUInt32 code, epicsUInt32 func,bool) OVERRIDE FINAL;
140 
141  virtual double clock() const OVERRIDE FINAL
142  {SCOPED_LOCK(evrLock);return eventClock;}
143  virtual void clockSet(double) OVERRIDE FINAL;
144 
145  epicsUInt16 clockMode() const;
146  void clockModeSet(epicsUInt16 mode);
147 
148  virtual bool pllLocked() const OVERRIDE FINAL;
149 
150  virtual epicsUInt32 irqCount() const OVERRIDE FINAL {return count_hardware_irq;}
151 
152  virtual bool linkStatus() const OVERRIDE FINAL;
153  virtual IOSCANPVT linkChanged() const OVERRIDE FINAL{return IRQrxError;}
154  virtual epicsUInt32 recvErrorCount() const OVERRIDE FINAL{return count_recv_error;}
155 
156  virtual epicsUInt32 uSecDiv() const OVERRIDE FINAL;
157 
159  virtual bool extInhib() const OVERRIDE FINAL;
160  virtual void setExtInhib(bool) OVERRIDE FINAL;
161 
162  virtual epicsUInt32 tsDiv() const OVERRIDE FINAL
163  {SCOPED_LOCK(evrLock);return shadowCounterPS;}
164 
165  virtual void setSourceTS(TSSource) OVERRIDE FINAL;
166  virtual TSSource SourceTS() const OVERRIDE FINAL
167  {SCOPED_LOCK(evrLock);return shadowSourceTS;}
168  virtual double clockTS() const OVERRIDE FINAL;
169  virtual void clockTSSet(double) OVERRIDE FINAL;
170  virtual bool interestedInEvent(epicsUInt32 event,bool set) OVERRIDE FINAL;
171 
172  virtual bool TimeStampValid() const OVERRIDE FINAL;
173  virtual IOSCANPVT TimeStampValidEvent() const OVERRIDE FINAL {return timestampValidChange;}
174 
175  virtual bool getTimeStamp(epicsTimeStamp *ts,epicsUInt32 event) OVERRIDE FINAL;
176  virtual bool getTicks(epicsUInt32 *tks) OVERRIDE FINAL;
177  virtual IOSCANPVT eventOccurred(epicsUInt32 event) const OVERRIDE FINAL;
178  virtual void eventNotifyAdd(epicsUInt32, eventCallback, void*) OVERRIDE FINAL;
179  virtual void eventNotifyDel(epicsUInt32, eventCallback, void*) OVERRIDE FINAL;
180 
181  bool convertTS(epicsTimeStamp* ts);
182 
183  virtual epicsUInt16 dbus() const OVERRIDE FINAL;
184 
185  virtual epicsUInt32 heartbeatTIMOCount() const OVERRIDE FINAL {return count_heartbeat;}
186  virtual IOSCANPVT heartbeatTIMOOccured() const OVERRIDE FINAL {return IRQheartbeat;}
187 
188  virtual epicsUInt32 FIFOFullCount() const OVERRIDE FINAL
189  {SCOPED_LOCK(evrLock);return count_FIFO_overflow;}
190  virtual epicsUInt32 FIFOOverRate() const OVERRIDE FINAL
191  {SCOPED_LOCK(evrLock);return count_FIFO_sw_overrate;}
192  virtual epicsUInt32 FIFOEvtCount() const OVERRIDE FINAL {return count_fifo_events;}
193  virtual epicsUInt32 FIFOLoopCount() const OVERRIDE FINAL {return count_fifo_loops;}
194 
195  void enableIRQ(void);
196 
197  bool dcEnabled() const;
198  void dcEnable(bool v);
199  double dcTarget() const;
200  void dcTargetSet(double);
202  double dcRx() const;
204  double dcInternal() const;
205  epicsUInt32 dcStatusRaw() const;
206  epicsUInt32 topId() const;
207 
208  epicsUInt32 dummy() const { return 0; }
209  void setEvtCode(epicsUInt32 code) OVERRIDE FINAL;
210 
211  epicsUInt32 timeSrc() const;
212  void setTimeSrc(epicsUInt32 mode);
213 
214  static void isr(EVRMRM *evr, bool pci);
215  static void isr_pci(void*);
216  static void isr_vme(void*);
217  static void isr_poll(void*);
218 #if defined(__linux__) || defined(_WIN32)
219  const void *isrLinuxPvt;
220 #endif
221 
222  const Config * const conf;
223  volatile unsigned char * const base;
224  epicsUInt32 baselen;
227  mrf::auto_ptr<SFP> sfp;
228 private:
229 
230  // Set by ISR
231  volatile epicsUInt32 count_recv_error;
232  volatile epicsUInt32 count_hardware_irq;
233  volatile epicsUInt32 count_heartbeat;
234  volatile epicsUInt32 count_fifo_events;
235  volatile epicsUInt32 count_fifo_loops;
236 
237  epicsUInt32 shadowIRQEna;
238 
239  // Guarded by evrLock
240  epicsUInt32 count_FIFO_overflow;
241 
242  // scanIoRequest() from ISR or callback
243  IOSCANPVT IRQmappedEvent; // Hardware mapped IRQ
244  IOSCANPVT IRQheartbeat; // Heartbeat timeout
245  IOSCANPVT IRQrxError; // Rx link state change
246  IOSCANPVT IRQfifofull; // Fifo overflow
247 
248  // Software events
249  IOSCANPVT timestampValidChange;
250 
251  // Set by ctor, not changed after
252 
253  typedef std::vector<MRMInput*> inputs_t;
254  inputs_t inputs;
255 
256  typedef std::map<std::pair<OutputType,epicsUInt32>,MRMOutput*> outputs_t;
257  outputs_t outputs;
258 
259  std::vector<DelayModule*> delays;
260 
261  typedef std::vector<MRMPreScaler*> prescalers_t;
262  prescalers_t prescalers;
263 
264  typedef std::vector<MRMPulser*> pulsers_t;
265  pulsers_t pulsers;
266 
267  typedef std::vector<MRMCML*> shortcmls_t;
268  shortcmls_t shortcmls;
269 
270  MRMGpio gpio_;
271 
272  mrf::auto_ptr<EvrSeqManager> seq;
273 
274  // run when FIFO not-full IRQ is received
275  void drain_fifo();
276  epicsThreadRunableMethod<EVRMRM, &EVRMRM::drain_fifo> drain_fifo_method;
277  epicsThread drain_fifo_task;
278  epicsMessageQueue drain_fifo_wakeup;
279  static void sentinel_done(CALLBACK*);
280 
281  epicsUInt32 count_FIFO_sw_overrate;
282 
283  eventCode events[256];
284 
285  // Buffer received
286  CALLBACK data_rx_cb;
287 
288  // Periodic callback to detect when link state goes from down to up
289  CALLBACK poll_link_cb;
290  static void poll_link(CALLBACK*);
291 
292  enum timeSrcMode_t {
293  Disable, // do nothing
294  External, // shift out TS on upstream when reset (125) received on downstream
295  SysClk, // generate reset (125) from software timer, shift out TS on upstream
296  } timeSrcMode;
297  /* in practice
298  * timeSrcMode!=Disable -> listen for 125, react by sending shift 0/1 codes
299  * timeSrcMode==SysClk -> send soft 125 events
300  */
301  CALLBACK timeSrc_cb;
302 
303  // Set by clockTSSet() with IRQ disabled
304  double stampClock;
305  TSSource shadowSourceTS;
306  epicsUInt32 shadowCounterPS;
307  double eventClock;
308 
309  epicsUInt32 timestampValid;
310  epicsUInt32 lastInvalidTimestamp;
311  epicsUInt32 lastValidTimestamp;
312  static void seconds_tick(void*, epicsUInt32);
313 
314  // bit map of which event #'s are mapped
315  // used as a safty check to avoid overloaded mappings
316  epicsUInt32 _mapped[256];
317 
318  void _map(epicsUInt8 evt, epicsUInt8 func) { _mapped[evt] |= 1<<(func); }
319  void _unmap(epicsUInt8 evt, epicsUInt8 func) { _mapped[evt] &= ~( 1<<(func) );}
320  bool _ismap(epicsUInt8 evt, epicsUInt8 func) const { return (_mapped[evt] & 1<<(func)) != 0; }
321 
322  friend struct EVRMRMTSBuffer;
323 }; // class EVRMRM
324 
325 #endif // EVRMRML_H_INC
size_t nPS
Definition: drvem.h:101
virtual IOSCANPVT TimeStampValidEvent() const OVERRIDE FINAL
Definition: drvem.h:173
epicsUInt32 dummy() const
Definition: drvem.h:208
std::set< EVRMRMTSBuffer * > tbufs_t
Definition: drvem.h:62
virtual epicsUInt32 recvErrorCount() const OVERRIDE FINAL
Definition: drvem.h:154
size_t nCML
Definition: drvem.h:106
size_t interested
Definition: drvem.h:57
virtual double clock() const OVERRIDE FINAL
Definition: drvem.h:141
virtual epicsUInt32 FIFOOverRate() const OVERRIDE FINAL
Definition: drvem.h:190
virtual epicsUInt32 irqCount() const OVERRIDE FINAL
Definition: drvem.h:150
volatile unsigned char *const base
Definition: drvem.h:223
std::list< std::pair< EVR::eventCallback, void * > > notifiees_t
Definition: drvem.h:67
TSSource
Definition: evr.h:31
mrmDataBufTx buftx
Definition: drvem.h:225
outkind
Definition: drvemCML.h:23
eventCode()
Definition: drvem.h:74
size_t nOFPDly
Definition: drvem.h:104
virtual epicsUInt32 heartbeatTIMOCount() const OVERRIDE FINAL
Definition: drvem.h:185
const char * model
Definition: drvem.h:99
epicsUInt32 last_evt
Definition: drvem.h:60
Modular Register Map Event Receivers.
Definition: drvem.h:86
size_t nIFP
Definition: drvem.h:109
IOSCANPVT occured
Definition: drvem.h:65
notifiees_t notifiees
Definition: drvem.h:68
formFactor
virtual TSSource SourceTS() const OVERRIDE FINAL
Definition: drvem.h:166
size_t nORB
Definition: drvem.h:103
virtual epicsUInt32 tsDiv() const OVERRIDE FINAL
When using internal TS source gives the divider from event clock period to TS period.
Definition: drvem.h:162
EVRMRM * owner
Definition: drvem.h:52
size_t waitingfor
Definition: drvem.h:71
virtual void lock() const OVERRIDE FINAL
Definition: drvem.h:121
Definition: mrmspi.h:20
virtual epicsUInt32 FIFOLoopCount() const OVERRIDE FINAL
Definition: drvem.h:193
User implementation hook.
Definition: object.h:459
virtual epicsUInt32 FIFOEvtCount() const OVERRIDE FINAL
Definition: drvem.h:192
MRMCML::outkind kind
Definition: drvem.h:107
mrmBufRx bufrx
Definition: drvem.h:226
size_t nPul
Definition: drvem.h:100
virtual epicsUInt32 FIFOFullCount() const OVERRIDE FINAL
Definition: drvem.h:188
virtual IOSCANPVT linkChanged() const OVERRIDE FINAL
Definition: drvem.h:153
tbufs_t tbufs
Definition: drvem.h:63
bool again
Definition: drvem.h:72
epicsUInt32 last_sec
Definition: drvem.h:59
const Config *const conf
Definition: drvem.h:222
epicsUInt8 code
Definition: drvem.h:51
epicsMutex evrLock
Guards access to instance All callers must take this lock before any operations on this object...
Definition: drvem.h:96
mrf::auto_ptr< SFP > sfp
Definition: drvem.h:227
epicsUInt32 baselen
Definition: drvem.h:224
CALLBACK done_cb
Definition: drvem.h:70
virtual IOSCANPVT heartbeatTIMOOccured() const OVERRIDE FINAL
Definition: drvem.h:186
virtual void unlock() const OVERRIDE FINAL
Definition: drvem.h:122