Hello Pierre-Andre,
thank you for your help with the interrupt handling. To close this case I'll
attach my interrupt
handling code for the SIS 3100 to this post as a reference. Maybe someone wants
to do something
similar in the future.
I've decide to go for a C++ frontend therefore it is a class that handles
everything. The user only
has to provide a function pointer to the constructor that handles the interrupt
bitmask. The
interrupt handling is done with a timedwait within a separate thread.
Cheers,
Clemens
> Hello Clemens,
>
> The hardware readout is triggered by the interrupt within this thread. The
main thread poll on
> the data availability (from the rb) to filter/compose the frontend event.
> In a similar multi-threaded implementation presently used in a dark matter
experiment we start
> as many thread as necessary to constantly poll on the hardware for "data
fragment" collection.
> The event composition is done in the main thread through polling on the RBs.
>
> Depending on the trigger rate and readout time, we can afford to analyze the
data fragment at
> the thread level and add computed/summary information to the ring buffer on a
event-by-event
> basis. This facilitate the overall event filtering happening later on in our
event builder.
>
> "polling the trigger signal?", I don't understand. You can poll on the trigger
condition but
> then you don't need interrupt.
>
> The original Midas interrupt implementation was to let the interrupt function
set a acknowledge
> flag which is picked up by the standard midas polling function (user code) for
triggering the
> readout. This method ensure a minimal time spent in the IRQ and works fine for
a single thread.
>
> In regards of the CAEN V1742, we do have a VME driver for it, but it hasn't
been added to the
> Midas yet (quite recent), but please don't hesitate to send us a copy.
>
> Cheers, PAA
> |
/*!
\file sis3100.hh
\brief provides an interface for interrupt handling with the Struck SIS3100 VME interface
\author Clemens Sauerzopf <clemens.sauerzopf@oeaw.ac.at>
\date 06.08.2014
\version 1.0
*/
#ifndef __SIS3100_HH__
#define __SIS3100_HH__
#include<stdint.h>
#include<sys/types.h>
#if HAVE_MIDAS__
extern "C" {
#include "midas.h"
#include "sis3100/linux/sis3100_vme_calls.h"
#include "sis3100/linux/sis1100_var.h"
}
#else
#include <pthread.h>
#include "sis3100/linux/sis3100_vme_calls.h"
#include "sis3100/linux/sis1100_var.h"
#endif
//! interrupt frontend handling class for SIS 3100 VME interface with veto gate and trigger generation
/*!
This class provides an easy to use interface for handling interrupts with the Stuck SIS3100 VME
interface. When using this class create an instance and pass an unused device number to the
constructor and a function pointer to handle the interrupt.
The interrupt handling is done in a separate thread that waits with a timeout of 500 ms for a
SIGUSR1 signal from the SIS kernel driver. In case of a timeout the loop checks if a thread stop
signal from midas is present and then waits again for an interrupt. If an interrupt occurs the
interrupt vector is loaded and a veto gate is produced by the @ref startVeto function on the
NIM port 1. Afterwards a user supplied function that takes the interrupt bitask, the highest
interrupt level and its vector as arguments is executed. After that the interrupts get acknowledged
and the veto gate is closed.
This class uses a separate device to avoid race conditions and for the low level interface to the
irq setup.
*/
class sis3100 {
public:
sis3100(int sisDeviceNum, bool (*eventFunction)(int,int,int));
bool enableFrontInterrupts();
bool disbaleFrontInterrupts();
bool enableVMEInterrupts();
bool disbaleVMEInterrupts();
bool enableOutputs();
bool disableOutputs();
static inline void startVeto(int p) {s3100_control_write(p, 0x80, 0x00000001);}
static inline void stopVeto(int p) {s3100_control_write(p, 0x80, 0x00010000);}
static inline void startVeto2(int p) {s3100_control_write(p, 0x80, 0x00000002);}
static inline void stopVeto2(int p) {s3100_control_write(p, 0x80, 0x00020000);}
static inline void generateTrigger(int p) {s3100_control_write(p, 0x80, 0x02000000);}
inline bool isOpen() const {return (p==-1 ? false : true);}
inline void setIsRunning(bool isRun){isRunning = isRun;}
private:
int p; // SIS3100 device handler
u_int32_t iobits;
struct sis1100_irq_ctl irqctl;
struct sis1100_irq_get irqget;
struct sis1100_irq_ack irqack;
sigset_t mask, old_mask;
bool isRunning;
// for testing
#if HAVE_MIDAS__
midas_thread_t thread;
#else
pthread_t thread;
#endif
static
#if HAVE_MIDAS__
INT
#else
void*
#endif
interruptThread(void *param);
struct threadInit {
bool (*eventFunction)(int, int, int);
bool *isRunning;
int p; // SIS3100 device handler
u_int32_t *iobits;
struct sis1100_irq_ctl *irqctl;
struct sis1100_irq_get *irqget;
struct sis1100_irq_ack *irqack;
sigset_t mask;
struct timespec waitTime;
};
threadInit threadData;
};
#endif // compile guard
|