-static char *rcsId = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/Attic/hwship.c,v 6.25 2002-10-15 16:27:24 hadaq Exp $";
+static char *rcsId = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/Attic/hwship.c,v 6.26 2002-10-17 08:20:41 hadaq Exp $";
-#include <assert.h>
-#include <string.h>
-
-#include <sys/time.h>
-#include <syslog.h>
+#define _POSIX_C_SOURCE 199309L
+#include <unistd.h>
+#include <assert.h>
#include <stdint.h>
+#include <stdio.h>
#include <stdlib.h>
-
-#include <lvme.h>
+#include <string.h>
+#include <syslog.h>
+#include <time.h>
#include <allParam.h>
+#include <lvme.h>
+#include "subevt.h"
+#include "ipc_basis.h"
#include "hwship.h"
+static void toDbgBuf(HwShip *my)
+{
+ int i;
+
+ /* copy one sub evt from RC to memory */
+ for (i = 0; i < my->dbgBufLen; i++) {
+ my->dbgBuf[my->currDbgBuf][i] = LVme_getL(my->lvme, LVL2_OFFSET + i * sizeof(LVme_L));
+ }
+ my->currDbgBuf = (my->currDbgBuf + 1 < my->nDbgBufs) ? my->currDbgBuf + 1 : 0;
+}
+
+static void dumpDbgBufs(const HwShip *my)
+{
+ int i, j, bufNr;
+ FILE *f;
+ char n[512];
+
+ strcpy(n, my->name);
+ strcat(n, ".dump");
+
+ f = fopen(n, "w");
+ assert(f != NULL);
+
+ for (j = 0, bufNr = my->currDbgBuf; j < my->nDbgBufs; j++, bufNr = (bufNr + 1 < my->nDbgBufs) ? bufNr + 1 : 0) {
+ for (i = 0; i < my->dbgBufLen; i++) {
+ if (i % 4 == 0) { /* newline and the offset in the subEvt */
+ fprintf(f, "\n%08x:", i * sizeof(uint32_t));
+ }
+ fprintf(f, " 0x%08x", my->dbgBuf[bufNr][i]);
+ }
+ fputc('\n', f);
+ }
+
+ close(f);
+}
+
int conHwShip(HwShip *my, const char *name, const Param *param)
{
unsigned long cardBase;
int paramWasFound;
- int i;
assert(my != NULL);
Param_getInt(param, my->name, "cardbase", ¶mWasFound, &cardBase);
if (!paramWasFound) {
- syslog(LOG_WARNING,
- "Parameter %s(%s) not found, default = 0", my->name, "cardbase");
- cardBase = 0;
+ syslog(LOG_ERR, "Parameter %s(cardbase) not found", my->name);
+ return -1;
}
my->lvme = malloc(sizeof(LVme));
if (0 > conLVme(my->lvme, cardBase, 0x400000UL, 0x39UL, LVL2_OFFSET, 4)) {
- syslog(LOG_ERR, "HwShip on %p not found", cardBase);
+ syslog(LOG_ERR, "%s on %p not found", my->name, cardBase);
return -1;
}
/* Select VME-accessible register of LVL2-controller */
LVme_setW(my->lvme, LVL2_SEL_VMEREG, LVL2_SELMEM_VMEREG);
- my->currAddr = 0x7fffffff; /* behind end of memory */
+ my->currAddr = 0x7fffffff;
my->endOfData = 0;
+
+
+ my->dbgBufLen = sizeof(uint16_t) * LVL2_SIZE / sizeof(uint32_t);
+ my->nDbgBufs = 3;
+ my->dbgBuf[0] = my->dbgBuf0;
+ my->dbgBuf[1] = my->dbgBuf1;
+ my->dbgBuf[2] = my->dbgBuf2;
+ my->currDbgBuf = 0;
+ my->isDoomed = 0;
+
return 0;
}
void desHwShip(HwShip *my)
{
desLVme(my->lvme);
+ free(my->lvme);
}
void HwShip_requestBuffer(HwShip *my)
{
int i;
-#ifndef NDEBUG
syslog(LOG_DEBUG, "wait for data");
-#endif
while ((LVme_getL(my->lvme, LVL2_ACCESS_VMEREG) >> 16 & 0xffff) <= 2) {
#if 1
struct timespec tS, *t = &tS;
t->tv_sec = 0;
- t->tv_nsec = 010000000;
+ t->tv_nsec = 020000000;
nanosleep(t, NULL);
#endif
}
-#ifndef NDEBUG
syslog(LOG_DEBUG, "data available");
-#endif
i = my->bankRequested == 1 ? 0 : 1;
LVme_setL(my->lvme, LVL2_ACCESS_VMEREG, i);
+
+ assert(i == LVme_tstBitL(my->lvme, LVL2_ACCESS_VMEREG, 6));
my->bankRequested = i;
- my->currAddr = LVL2_DATASTART;
+ my->currAddr = LVL2_OFFSET + 0x4;
/* to indicate a buffer request state which is cleared by getEndOfData */
my->endOfData = 0;
}
-#define SHIP_NODATASIZE 16
-
int HwShip_readSubEvt(HwShip *my, void *subEvt)
{
uint32_t *data = (uint32_t *) subEvt;
- int lastAddr;
- int currAddr = my->currAddr;
- int size, i;
- char str[200], buff[200];
- unsigned long *tempPtr;
-
- size = LVme_getL(my->lvme, currAddr);
-
- lastAddr = currAddr + size;
- my->currAddr = lastAddr;
-
- /* skip empty subevent, nobody will realize this */
-#if 1
- if (size <= SHIP_NODATASIZE)
- return 1;
+ int firstAddr;
+ size_t size;
+
+ assert(my->bankRequested == bankConfirmed(my));
+ assert(endOfData(my) <= LVL2_OFFSET + sizeof(uint16_t) * LVL2_SIZE);
+ size = LVme_getL(my->lvme, my->currAddr);
+#if 0
+ assert(size < sizeof(uint32_t) * 1600); /* whereever the 1600 comes from */
+#else
+ if (my->isDoomed) {
+ dumpDbgBufs(my);
+ syslog(LOG_EMERG, "%s: was doomed in previous buffer, dump buffer again and abort", my->name);
+ abort();
+ }
+ if (size >= sizeof(uint32_t) * 1600) {
+ dumpDbgBufs(my);
+ syslog(LOG_EMERG, "%s: corrupted subEvt, dump buffer and try one more", my->name);
+ my->currAddr = endOfData(my);
+ my->isDoomed = 1;
+ SubEvt_setDecoding(subEvt, 0x00020001);
+ SubEvt_setSize(subEvt, 0x10);
+ SubEvt_setId(subEvt, 399 | 0x80000000);
+ SubEvt_setTrigNr(subEvt, 0);
+ return 0;
+ }
#endif
/* copy one sub evt from RC to memory */
- *data++ = size;
- i = 0;
- /* we are not sure what the maximum number of words is allowed in the ipcs*/
- while (((currAddr += 4) < lastAddr) && (i < 0x1600)) {
- *data++ = LVme_getL(my->lvme, currAddr);
- i++;
+ for (firstAddr = my->currAddr; my->currAddr - firstAddr < size; my->currAddr += 4) {
+ *data++ = LVme_getL(my->lvme, my->currAddr);
}
- if (size > 0x1900) {
- syslog(LOG_ERR, "Error, size too large: %.8x", size);
-
- tempPtr = (unsigned long *)(data - 0x1600);
-
- str[0] = 0;
- for (i = 0; i < 100; i++) {
- sprintf(buff, "%.8x ", tempPtr[i]);
- strcpy((char *) ((unsigned int) str + strlen(str)), buff);
- if (((i + 1) % 4) == 0) {
- syslog(LOG_ERR, str);
- str[0] = 0;
- }
- }
- if ((i % 4)) {
- syslog(LOG_ERR, str);
- str[0] = 0;
- }
- }
-#ifndef NDEBUG
syslog(LOG_DEBUG, "subEvt: %s", SubEvt_2charP(subEvt));
-#endif
return 0;
}
+
#ifndef HwShip_H
#define HwShip_H
void HwShip_requestBuffer(HwShip *my);
-static int bankConfirmed(HwShip *my)
+static int HwShip_isEmpty(HwShip *my)
{
- return LVme_tstBitL(my->lvme, LVL2_ACCESS_VMEREG, 7);
+ return my->currAddr >= my->endOfData;
}
-static void HwShip_getEndOfData(HwShip *my)
+int HwShip_readSubEvt(HwShip *my, void *subEvt);
+
+static int HwShip_isBufRequested(HwShip *my)
{
- my->endOfData = LVme_getL(my->lvme, LVL2_OFFSET) - 2 + LVL2_OFFSET;
+ return my->endOfData == 0;
}
-static int HwShip_isBusy(HwShip *my)
+static void HwShip_getEndOfData(HwShip *my)
{
- return my->bankRequested != bankConfirmed(my);
+ my->endOfData = LVme_getL(my->lvme, LVL2_OFFSET) - 2 + LVL2_OFFSET;
+ toDbgBuf(my);
}
-static int HwShip_isEmpty(HwShip *my)
+static int bankConfirmed(HwShip *my)
{
- return my->currAddr >= my->endOfData;
+ return LVme_tstBitL(my->lvme, LVL2_ACCESS_VMEREG, 7);
}
-static int HwShip_isBufRequested(HwShip *my)
+static int HwShip_isBusy(HwShip *my)
{
- return my->endOfData == 0;
+ return my->bankRequested != bankConfirmed(my);
}
-int HwShip_readSubEvt(HwShip *my, void *subEvt);
-
#endif