2 * \class Vd80Device Static Library
3 * \author Julian Lewis BE/CO/HT Julian Lewis
6 * This library exists in two forms as a ".so" shared object, and for
7 * thoes who are unwilling to use a dynamic library there is a ".a" static
8 * version as well. For the dynamic link stub library see seperate doccument.
10 * The vd80 driver exposes a minimum functionality of the boards capabilities.
11 * More functions can be added later if needed.
13 * In the current driver the following capabilities are provided.
14 * 1) Setting up of the trigger
15 * 2) Setting up of the clock
16 * 3) Setting up the post trigger sample size
17 * 4) Issuing module commands like Start, Stop, Trigger
18 * 5) Reading the sample buffer for a given channel via DMA
19 * 6) Connecting to and waiting for module interrupts
21 * A library test program using the dynamic library is available, the
22 * executable is named "vd80libTst".
27 * Standard error codes are available.
31 /** All went OK, No error */ Vd80ErrSUCCESS,
32 /** Function is not implemented on this device */ Vd80ErrNOT_IMP,
33 /** Invalid Start value for this device */ Vd80ErrSTART,
34 /** Invalid Mode value for this device */ Vd80ErrMODE,
35 /** Invalid Clock value for this device */ Vd80ErrCLOCK,
36 /** Can't open a driver file handle, fatal */ Vd80ErrOPEN,
37 /** Can't connect to that interrupt */ Vd80ErrCONNECT,
38 /** No connections to wait for */ Vd80ErrWAIT,
39 /** Timeout in wait */ Vd80ErrTIMEOUT,
40 /** Queue flag must be set 0 queueing is needed */ Vd80ErrQFLAG,
41 /** IO or BUS error */ Vd80ErrIO,
42 /** Module is not enabled */ Vd80ErrNOT_ENAB,
43 /** Not available for INTERNAL sources */ Vd80ErrSOURCE,
44 /** Value out of range */ Vd80ErrVOR,
45 /** Bad device type */ Vd80ErrDEVICE,
46 /** Bad address */ Vd80ErrADDRESS,
47 /** Can not allocate memory */ Vd80ErrMEMORY,
48 /** Shared library error, can't open object */ Vd80ErrDLOPEN,
49 /** Shared library error, can't find symbol */ Vd80ErrDLSYM,
50 /** Can't open sampler device driver */ Vd80ErrDROPEN,
51 /** Invalid handle */ Vd80ErrHANDLE,
52 /** Invalid module number, not installed */ Vd80ErrMODULE,
53 /** Invalid channel number for this module */ Vd80ErrCHANNEL,
55 /** The total number of possible error codes */ Vd80ERRORS
59 * Set the debug level. The values in the first byte control the debug
60 * print level on the console. Much of this information is prionted by
61 * the driver and can slow things down a lot. The second byte controls
62 * hardware and software emulation. This is for testing purposes only.
66 /** All assertion violations (BUGS) printed */ Vd80DebugASSERTION = 0x01,
67 /** Trace all driver calls */ Vd80DebugTRACE = 0x02,
68 /** Warnings such as bad call parameters */ Vd80DebugWARNING = 0x04,
69 /** Hardware module errors, bus error etc */ Vd80DebugMODULE = 0x08,
70 /** Extra information */ Vd80DebugINFORMATION = 0x10,
71 /** Turn on driver emulation, no hardware access */ Vd80DebugEMULATION = 0x100,
75 * The number of bits in the debug mask that can be set to determin
76 * the driver and library debug information printout.
79 #define Vd80DebugLEVELS 6
82 * The debug level can be controlled for any client with an open driver handle.
83 * The PID of the client can be specified, a value of "0" is the callers PID.
87 /** PID of client, or zero for this PID */ int ClientPid;
88 /** The debug flag bits specify the level */ Vd80DebugFlag DebugFlag;
92 * We sometimes need a bit mask to specify modules/channels when an
93 * operation or command is applied to many modules at the same time.
94 * Obviously we can declare more modules if needed.
98 /** No module selected */ Vd80ModNONE = 0x0000,
99 /** Select module 1 */ Vd80Mod01 = 0x0001,
100 /** Select module 2 */ Vd80Mod02 = 0x0002,
101 /** Select module 3 */ Vd80Mod03 = 0x0004,
102 /** Select module 4 */ Vd80Mod04 = 0x0008,
103 /** Select module 5 */ Vd80Mod05 = 0x0010,
104 /** Select module 6 */ Vd80Mod06 = 0x0020,
105 /** Select module 7 */ Vd80Mod07 = 0x0040,
106 /** Select module 8 */ Vd80Mod08 = 0x0080,
107 /** Select module 9 */ Vd80Mod09 = 0x0100,
108 /** Select module 10 */ Vd80Mod10 = 0x0200,
109 /** Select module 11 */ Vd80Mod11 = 0x0400,
110 /** Select module 12 */ Vd80Mod12 = 0x0800,
111 /** Select module 13 */ Vd80Mod13 = 0x1000,
112 /** Select module 14 */ Vd80Mod14 = 0x2000,
113 /** Select module 15 */ Vd80Mod15 = 0x4000,
114 /** Select module 16 */ Vd80Mod16 = 0x8000,
115 /** All modules selected */ Vd80ModALL = 0xFFFF
119 * A resonable limit on reserved memory defined by the number of driver
120 * module contexts is set at 16. Should we need more the driver must be
121 * recompiled and delivered with the new value.
124 #define Vd80MODULES 16
127 * We sometimes need a bit mask to specify modules/channels when an
128 * operation or command is applied to many modules at the same time.
129 * Obviously we can declare more modules if needed.
133 /** No channel selected */ Vd80ChnNONE = 0x0000,
134 /** Select channel 1 */ Vd80Chn01 = 0x0001,
135 /** Select channel 2 */ Vd80Chn02 = 0x0002,
136 /** Select channel 3 */ Vd80Chn03 = 0x0004,
137 /** Select channel 4 */ Vd80Chn04 = 0x0008,
138 /** Select channel 5 */ Vd80Chn05 = 0x0010,
139 /** Select channel 6 */ Vd80Chn06 = 0x0020,
140 /** Select channel 7 */ Vd80Chn07 = 0x0040,
141 /** Select channel 8 */ Vd80Chn08 = 0x0080,
142 /** Select channel 9 */ Vd80Chn09 = 0x0100,
143 /** Select channel 10 */ Vd80Chn10 = 0x0200,
144 /** Select channel 11 */ Vd80Chn11 = 0x0400,
145 /** Select channel 12 */ Vd80Chn12 = 0x0800,
146 /** Select channel 13 */ Vd80Chn13 = 0x1000,
147 /** Select channel 14 */ Vd80Chn14 = 0x2000,
148 /** Select channel 15 */ Vd80Chn15 = 0x4000,
149 /** Select channel 16 */ Vd80Chn16 = 0x8000,
150 /** All channels selected */ Vd80ChnALL = 0xFFFF
154 * 16 channels are supported on a VD80 module
157 #define Vd80CHANNELS 16
160 * The VD80 module has one state for all channels.
162 * When the module is in the IDLE state data can be read/written to
163 * the modules sample memory. When in IDLE no samples are taken.
165 * When the module receives either a software of external start, it begins
166 * sampling at the selected clock rate. All samples for all channels are
167 * stored in each channel buffer. Each chanel has 32Mb of memory.
168 * The module is in the PRETRIGGER state after being started.
170 * When the module receives either s software or external trigger, it
171 * continues sampling until it either receives a software stop, or the
172 * specified number of post trigger samples have been read. The module
173 * is in the POSTTRIGGER state until it stops.
175 * When the module has been stopped, it moves back to the IDLE state
179 /** Not known/initialized */ Vd80StateNOT_SET = 0,
180 /** Ready to do something */ Vd80StateIDLE = 1,
181 /** Waiting for trigger */ Vd80StatePRETRIGGER = 2,
182 /** Sampling, device busy */ Vd80StatePOSTTRIGGER = 3,
183 /** Total number of states */ Vd80STATES = 4
187 * Standard status definitions:
188 * These status bits are set through the generic SKEL driver.
189 * The module is not available for sampling if the DISABLE bet is set.
190 * If there is a hardware failure the HARDWARE_FAIL bit is set.
191 * On the VD80 the inputs are checked for short circuit, the hardware
192 * failure is then set.
193 * The VD80 must be configured correctly so that the address maps are
194 * properly set up. In particular the A24D32, CSR and MBLT64 address spaces
195 * must be setup by the driver. These addresses must conform to the
196 * auto slot configuration settings. See VD80 manual for mor details.
197 * Incorrect configuration settings will lead to the BUS_FAULT bit being set.
198 * For testing purposes the debug level can be set to EMULATION. In this case
199 * the VD80 driver provides a simple hardware emulation by mirroring the
200 * hardware address map in the module context memory.
201 * Again for testing only, if EMULATION is on, there is no need to have a
202 * real hardware module installed. In this case the NO_HARDWARE bit is set.
206 /** Hardware is not enabled */ Vd80StatusDISABLED = 0x001,
207 /** Hardware has failed */ Vd80StatusHARDWARE_FAIL = 0x002,
208 /** Bus error(s) detected */ Vd80StatusBUS_FAULT = 0x004,
209 /** Hardware emulation ON */ Vd80StatusEMULATION = 0x008,
210 /** Hardware debug mode */ Vd80StatusHARDWARE_DBUG = 0x100
214 * There are 3 version parameters.
215 * The Library Version is the UTC time compilation date of the library.
216 * The Drvver Version is the UTC time compilation date of the driver.
217 * The Module Version is a string returned from the VD80 configuration space.
218 * The Module Version string size is defined by VERSION_SIZE
221 #define Vd80VERSION_SIZE 64
224 /** DLL Library Compile date */ unsigned int LibraryVersion;
225 /** Drvr Compile date */ unsigned int DriverVersion;
226 /** Module version string */ char ModVersion[Vd80VERSION_SIZE];
230 * Inputs can be specified as EXTERNAL in which case the EDGE
231 * and TERMINATION of the signal SOURCE must be provided. When
232 * the SOURCE is INTERNAL the EDGE and TERMINATION specification
233 * is internally determined by the module defaults.
234 * Each input has a Lemo connector on the VD80 front pannel.
238 * An input is sensative to either a rising or falling edge
242 /** Use the rising edge of the input signal */ Vd80EdgeRISING,
243 /** Use the falling edge of the input signal */ Vd80EdgeFALLING,
244 /** The possible edges */ Vd80EDGES
248 * The input of a VD80 can be either not terminated, or terminated
249 * internally with 50 Ohms.
253 /** No internal termination */ Vd80TerminationNONE,
254 /** 50 Ohms internal termination */ Vd80Termination50OHM,
255 /** Possible terminations */ Vd80TERMINATIONS
259 * The input can be sourced internally, or an external signal
260 * can be used at the Lemo input.
264 /** Signal is generated internally */ Vd80SourceINTERNAL,
265 /** Signal arrives on input Lemo */ Vd80SourceEXTERNAL,
266 /** Possible sources */ Vd80SOURCES
270 * This structure is used to define the parameters of an input,
271 * its edge, termination and source. Each input has a corresponding
272 * Lemo connector on the VD80 front pannel.
276 /** The signal edge to be used */ Vd80Edge Edge;
277 /** The termination to use */ Vd80Termination Termination;
278 /** Possible sources */ Vd80Source Source;
282 * The VD80 ADC is 16=Bits signed twos compliment. For generic libraries such
283 * as the stub library that handles many module types of varrying prescision
284 * the Datum Size is needed. The VD80 has a fixed Datum Size DatumSize16.
285 * The Datum Size is needed by the DMA mechansim to know how to break up and
286 * byte order the transfer buffer.
287 * Sample buffers are read back from a sampler and contain the acquired
288 * data for a channel. The buffer pointer should be cast according to
289 * the buffer DatumSize. The Datum size is actually the number of bytes in
290 * a Sample, not the exact number of bits.
294 /** Cast buffer to char */ Vd80DatumSize08 = 1,
295 /** Cast buffer to short */ Vd80DatumSize16 = 2,
296 /** Cast buffer to int */ Vd80DatumSize32 = 4
300 * Trigger configuration, trigger delay and min pre trigger samples
304 /** Time to wait after trig in sample intervals */ int TrigDelay;
305 /** Mininimum number of pretrig samples */ int MinPreTrig;
309 * A VD80 buffer is filled accross a DMA transfer from the modules sample
310 * buffer memory for a channel. The User must allocate at least
311 * (BSze x DatumSize) bytes of memory. BSze is the total buffer size measured
312 * in Samples, and Post is the number of POSTTRIGGER samples you want. Obviously
313 * Post must be less than BSze.
314 * The DMA mechanism of the VD80 is only able to transfer memory in chunks of
315 * 32 Samples. So the actual trigger position TPOS is adjusted to give at least
316 * Post Samples and returned to the User. In a similar way the Actual number of
317 * available samples read back from the hardware is ASze.
321 /** Address of alloocated sample memory */ void *Addr;
322 /** Buffer size in samples (DatumSize) */ int BSze;
323 /** Requested number of post samples */ int Post;
324 /** Actual position of trigger */ int Tpos;
325 /** Actual number of samples in buffer */ int ASze;
326 /** Pre-trigger status register */ int Ptsr;
330 * When waiting for interrupts from VD80 modules, you may or may not want the
331 * driver to provide you with a queue. Setting the Queue Flag OFF will guarantee
332 * a hard real time correspondance between the client thread and the instant
333 * module state. However if many modules are interrupting at exactly the same time
334 * then because you have Queueing OFF, then interrupts would be missed.
338 /** 0 => Client interrupt queueing ON */ Vd80QueueFlagON,
339 /** 1 => and OFF */ Vd80QueueFlagOFF
343 * The VD80 is capable of providine interrupts when the module receives a trigger,
344 * or when the acquisition data becomes ready, IE when its state changes from
345 * POSTTRIGGER to IDLE. The VD80 also monitors itself and its inputs and can
346 * provide an interrupt for some hardware failures.
350 /** Trigger interrupt */ Vd80IntrMaskTRIGGER = 0x1,
351 /** Data ready interrupt */ Vd80IntrMaskACQUISITION = 0x2,
352 /** Hardware error interrupt */ Vd80IntrMaskERR = 0x4,
353 /** Possible interrupts */ Vd80INTR_MASKS = 3
357 * Once an interrupt for a client occurs an interrupt structure is placed on its
358 * Queue. If Queueing is OFF the queuesize is limited to ONE entry, otherwise
359 * the Queue Size is a system parameter (default 32).
360 * The Client calls the drivers "read()" entry an is returned either a timeout or
361 * a completed Intr structure. The two situations can be destinguished by the read()
362 * returned byte count. In the case of a timeout zero is returned, otherwise the
363 * returned value is sizeof(Vd80Intr). When a Intr structure is read from the queue
364 * it contains a Mask value wit only a single bit set, the Time that the interrupt
365 * happened, the module from which the interrupt came, the channel, the number of
366 * remaining Intr structures on the Queue, and the number of Missed interrupts due
367 * to Queue overflow. In the VD80 case the Channel is always zero because all
368 * channels have exactly the same state.
372 /** Single interrupt source bit */ Vd80IntrMask Mask;
373 /** Time of trigger */ struct timespec Time;
374 /** The module number 1..N */ unsigned int Module;
375 /** The channel (Always zero on a VD80) */ unsigned int Channel;
376 /** Number of remaining entries on queue */ unsigned int QueueSize;
377 /** Queue overflow missed count */ unsigned int Missed;
381 * Open a VD80 driver handle. Beware that if the user is using a multi-threaded
382 * application in which more than one thread waits for an interrupt, then each
383 * thread must open a driver handle independantly and hence each thread gets
384 * its own Queue. vd80OpenHandle either manages to open the driver and return
385 * a posative integer value, or it fails and return a negative or zero value.
388 int vd80OpenHandle();
391 * Close a VD80 driver handle. This routine never fails, even with a garbage
392 * file descriptor. Close marks a Client Context as available and detaches it
393 * from any interrupts it connected to. Close is always called for open files
394 * when a client is either killed or exits.
397 void vd80CloseHandle(int fd);
400 * The debug mask bits are described above (Vd80DebugFlag).
401 * Notice that by putting the PID
402 * of a client in the Debug structure it is possible to turn logging on at
403 * various levels, A PID value of zero always means the Current process.
404 * Setting EMULATION forces the driver to emulate for all clients.
407 Vd80Err vd80SetDebug(int fd, Vd80Debug *debug);
410 * Read a clients debug mask, supply the PID or zero in Debug and get back
411 * the current Debug mask.
414 Vd80Err vd80GetDebug(int fd, Vd80Debug *debug);
417 * Reset is the equivalent to a VME bus reset. All settings and data on
418 * the module will be lost. This function is very dangerous on a VD80 as
419 * the module looses its configuration. Do not call this function in an
420 * initialization. In fact just don't call it unless you are debugging.
421 * It also kills interrupt subscriptions of other clients.
424 Vd80Err vd80ResetMod(int fd, int module);
427 * Each VD80 channel has its own 16-Bit ADC. The instantaneous ADC value
428 * can be read via this function. These values can be used by experts to
429 * recallibrate a VD80 module.
430 * Calibrate requires that zero and Max volts are applied to an input
431 * and the Adc value then read back. Once done the values obtained can
432 * be used to calibrate the module.
433 * The VD80 was calibrated by the factory, overwriting the factory settings
434 * isn't a good idea unless you know what you are doing. For this reason
435 * the Calibration library routine has been suppressed.
438 Vd80Err vd80GetAdcValue(int fd, int module, int channel, int *adc);
441 * Get the state of a VD80 module. See (Vd80State) above for possible States.
442 * The VD80 does not support a state for each channel, so the channel parameter
446 Vd80Err vd80GetState(int fd, int module, int channel, Vd80State *state);
449 * Get the generic status word for a given VD80 module.
452 Vd80Err vd80GetStatus(int fd, int module, Vd80Status *status);
455 * Get the VD80 module DatumSize (See Vd80Status above). This function will always
456 * return DatumSize16 for the VD80.
459 Vd80Err vd80GetDatumSize(int fd, Vd80DatumSize *datsze);
462 * Discover how many VD80 module are actually installed in this VME crate.
463 * N.B. The result can be zero when NO_HARDWEARE status is set.
466 Vd80Err vd80GetModCount(int fd, int *count);
469 * Get the number of channels supported by the VD80 module. This function
470 * will always return 16 on a VD80 module.
473 Vd80Err vd80GetChnCount(int fd, int *count);
476 * Get the Hardware, Driver and Library versions, see Vd80Version above.
479 Vd80Err vd80GetVersion(int fd, int module, Vd80Version *version);
482 * Set up the VD80 module trigger input, edge, termination and source.
483 * One bit is set in the module mask for each module you want to set.
484 * The settings are for the entire module and channels is ignored.
487 Vd80Err vd80SetTrigger(int fd, Vd80Mod modules, Vd80Chn channels, Vd80Input *trigger);
490 * Get trigger setting for one specified module 1..N
491 * The settings are for the entire module and channels is ignored.
494 Vd80Err vd80GetTrigger(int fd, int module, int channel, Vd80Input *trigger);
497 * Set up the VD80 module clock input, edge, termination and source.
498 * One bit is set in the module mask for each module you want to set.
499 * The settings are for the entire module and channels is ignored.
502 Vd80Err vd80SetClock(int fd, Vd80Mod modules, Vd80Chn channels, Vd80Input *clock);
505 * Get clock setting for one specified module 1..N
506 * The settings are for the entire module and channels is ignored.
509 Vd80Err vd80GetClock(int fd, int module, int channel, Vd80Input *clock);
512 * The VD80 has a 200KHz internal clock. This clock can be devided to provide
513 * an internal clock frequency of 200/(N+1) KHz. Notice the the devisor N
514 * has one added to it to avoid the division by zero.
517 Vd80Err vd80SetClockDivide(int fd, Vd80Mod modules, Vd80Chn channels, unsigned int divisor);
520 * Get the clock divisor N. The internal clock frequency is 200/(N+1) Khz
523 Vd80Err vd80GetClockDivide(int fd, int module, int channel, unsigned int *divisor);
526 * Get trigger configuration params, delay and min pretrig samples */
529 Vd80Err vd80GetTriggerConfig(int fd, int mod, int chn, Vd80TrigConfig *ctrg);
532 * Set trigger configuration params, delay and min pretrig samples */
535 Vd80Err vd80SetTriggerConfig(int fd, unsigned int mods, unsigned int chns, Vd80TrigConfig *ctrg);
538 * Buffers contain samples that occur before and after the trigger.
539 * Any byte ordering operations are performed by the library.
540 * The user specifies the number of post trigger samples and the size
541 * of the buffer. In some hardware such as the VD80 the DMA transfers
542 * are carried out in chunks. Thus the exact triigger position within
543 * the buffer is adjusted to the nearset size/post boundary. Hence the
544 * actual number of pre/post trigger samples may vary.
545 * The user is responsible for allocating the buffer. If there are
546 * performance issues it is preferable to allocate the buffer on a
547 * 4096 byte page aligned block as follows ...
548 * if (posix_memalign((void **) &buf,4096,BUF_SHORTS*sizeof(short)))
549 * perror("Cant allocate buffer");
550 * See Vd80Buffer above.
551 * This function sets the post trigger register on the VD80 hardware.
552 * The settings are for the entire module and channels is ignored.
555 Vd80Err vd80SetBufferSize(int fd, Vd80Mod modules, Vd80Chn channels, int size, int post);
558 * Start acquireing samples, the state will change from IDLE to PRETRIGGER,
559 * and the VD80 will copy ADC values to channel sample memory.
560 * One bit is set in the module mask for each module you want to set.
561 * The settings are for the entire module and channels is ignored.
564 Vd80Err vd80StrtAcquisition(int fd, Vd80Mod modules, Vd80Chn channels);
567 * Start acquireing post samples, the state will change from PRETRIGGER to POSTTRIGGER,
568 * and the VD80 will copy ADC Post values to channel sample memory.
569 * One bit is set in the module mask for each module you want to set.
570 * The settings are for the entire module and channels is ignored.
573 Vd80Err vd80TrigAcquisition(int fd, Vd80Mod modules, Vd80Chn channels);
576 * Stop acquireing post samples, the state will change from ANY to IDLE,
577 * and the VD80 will copy ADC values to channel sample memory.
578 * One bit is set in the module mask for each module you want to set.
579 * The settings are for the entire module and channels is ignored.
582 Vd80Err vd80StopAcquisition(int fd, Vd80Mod modules, Vd80Chn channels);
585 * If the state is IDLE the IO buffer pointer is set to the channel
586 * Specified. Do NOT call this function, it is used by GetBuffer and
587 * is only for experts.
588 * One bit is set in the module mask for each module you want to set.
589 * Only one bit in the channel mask should be set.
592 Vd80Err vd80ReadAcquisition(int fd, Vd80Mod modules, Vd80Chn channels);
595 * Connect to an interrupt on a given module. See Vd80IntrMask.
596 * The settings are for the entire module and channels is ignored.
599 Vd80Err vd80Connect(int fd, Vd80Mod modules, Vd80Chn channels, Vd80IntrMask imask);
602 * Set your timeout value in milliseconds.
603 * The timeout can be independantly set by each thread wit its own open handle.
606 Vd80Err vd80SetTimeout(int fd, int tmout);
609 * Get the open handle timeout in milliseconds.
612 Vd80Err vd80GetTimeout(int fd, int *tmout);
615 * Set queueing on or off for a given handle. See Vd80QueueFlag
618 Vd80Err vd80SetQueueFlag(int fd, Vd80QueueFlag flag);
621 * Get queue falg for a given handle. See Vd80QueueFlag
624 Vd80Err vd80GetQueueFlag(int fd, Vd80QueueFlag *flag);
627 * Wait for an interrupt or a timeout. See Vd80Intr
628 * In the case of a timeout the return error is Vd80ErrTIMEOUT
629 * You can connect to any bit you want and wait for it.
630 * Using Simulate Interrupt you get a nice synchronization method.
633 Vd80Err vd80Wait(int fd, Vd80Intr *intr);
636 * Simulate an interrupt, the event will be put on all connected clients
637 * queue, and they will be woken up with whatever you specified.
638 * This is usefull for testing, and for synchronization between threads.
641 Vd80Err vd80SimulateInterrupt(int fd, Vd80Intr *intr);
644 * Read a buffer from a specified module and channel. See Vd80Buffer.
645 * This functions stops the module and starts a DMA transfer into User
646 * address space. Be sure you allocated memory correctly. When the
647 * transfer is complete the function returns.
650 Vd80Err vd80GetBuffer(int fd, int module, int channel, Vd80Buffer *buffer);