--- /dev/null
+#define _POSIX_C_SOURCE 199309L
+#include <unistd.h>
+
+#include <sys/time.h>
+
+#include <lvme.h>
+
+#include "subevt.h"
+#include "param.h"
+
+#define MU_FIFO 0x04000000UL
+#define MU_EVT_COUNT 0x000e8014UL
+#define MU_FIFO_STATUS 0x06000008UL
+
+struct HardwareS {
+ LVme *lvme;
+ LVme_L evtCount;
+ LVme_L old_evtCount;
+ size_t maxSubEvtSize;
+};
+
+#include "hardware.h"
+
+size_t Hardware_maxSubEvtSize(const Hardware *my)
+{
+ return my->maxSubEvtSize;
+}
+
+#include <hadesstd.h>
+
+int Hardware_inSpill(const Hardware *my)
+{
+ return 0;
+}
+
+Hardware *newHardware(void)
+{
+ Hardware *my;
+ unsigned long cardBase;
+ Param *param;
+
+ my = allocMem(sizeof(Hardware));
+ my->maxSubEvtSize = 3 * SubEvt_hdrSize() + 10 * sizeof(UInt4);
+
+ my->evtCount = 0;
+ my->old_evtCount = 0;
+
+ param = allocMem(sizeof(Param));
+ conParam(param, "param.tcl");
+ cardBase = Param_getVal(param, "mu", "cardbase");
+ desParam(param);
+
+ my->lvme = allocMem(sizeof(LVme));
+ if (0 > conLVme(my->lvme, cardBase, 0x8000000UL, 0x09UL, 0, 0)) {
+ msglog(LOG_ERR, "MU on %p not found\n", cardBase);
+ return NULL;
+ }
+
+ return my;
+}
+
+void deleteHardware(Hardware *my)
+{
+ desLVme(my->lvme);
+ freeMem(my->lvme);
+ freeMem(my);
+}
+
+void Hardware_waitForTrigger(Hardware *my, void *partEvt)
+{
+
+ /*
+ only read the Matching Unit Count register, when all pending
+ events are processed. This is recommended, because it is very
+ "expensive" to read from an Sharc Register in the Matching Unit.
+ */
+
+ if(my->evtCount != my->old_evtCount) {
+ my->evtCount++;
+ return;
+ }
+
+ my->old_evtCount=LVme_getL(my->lvme, MU_EVT_COUNT);
+ while (my->evtCount == my->old_evtCount) {
+#if 1
+ struct timespec tS, *t = &tS;
+
+ t->tv_sec = 0;
+ t->tv_nsec = 400000000UL;
+ nanosleep(t, NULL);
+ my->old_evtCount=LVme_getL(my->lvme, MU_EVT_COUNT);
+#endif
+ }
+
+ my->evtCount++;
+}
+
+void readoutTrig(Hardware *my, void *subEvt)
+{
+ UInt4 *data;
+ size_t size;
+ int i;
+
+ data = SubEvt_begin(subEvt);
+
+
+ if (! ((LVme_getW(my->lvme, MU_FIFO_STATUS) >> 3) &0x1) ) {
+ LVme_getW(my->lvme, MU_FIFO);
+ }
+
+ *data++ = LVme_getW(my->lvme, MU_FIFO) & 0xffff;
+ *data++ = LVme_getW(my->lvme, MU_FIFO) & 0xffff;
+ *data++ = LVme_getW(my->lvme, MU_FIFO) & 0xffff;
+ *data++ = LVme_getW(my->lvme, MU_FIFO) & 0xffff;
+ SubEvt_setDecoding(subEvt, SubEvtDecoding_32bitData);
+
+ while (data < SubEvt_end(subEvt)) {
+ *data++ = LVme_getW(my->lvme, MU_FIFO) & 0xffff;
+ }
+
+ msglog(LOG_DEBUG, "subEvt: %s\n", SubEvt_2charP(subEvt));
+}
+
+void Hardware_readout(Hardware *my, void *partEvt)
+{
+ void *subEvt = SubEvt_data(partEvt);
+ static unsigned long trigNr = 0;
+ UInt1 trigTag;
+
+ SubEvt_setDecoding(partEvt, SubEvtDecoding_SubEvts);
+
+ readoutTrig(my, subEvt);
+ trigTag = SubEvt_trigNr(subEvt);
+ subEvt = SubEvt_next(partEvt, subEvt);
+
+ SubEvt_setSize(partEvt, (char *)subEvt - (char *)partEvt);
+ SubEvt_setId(partEvt, 0);
+ SubEvt_setTrigNr(partEvt, ((trigNr++) << 8) | trigTag);
+ msglog(LOG_DEBUG, "partEvt: %s\n", SubEvt_2charP(partEvt));
+}
+
+
+