Back Midas Rome Roody Rootana
  Midas DAQ System  Not logged in ELOG logo
Message ID: 493     Entry time: 01 Jul 2008
Author: Jimmy Ngai 
Topic: Forum 
Subject: CAEN V792N QDC with MIDAS 
Dear All,

I have a problem when testing the V792N 16 CH QDC with the V1718 VME-USB 
Bridge on Scientific Linux 5.1 i386 (kernel 2.6.18-53.1.21.e15).

The problem is that the V792N does not response normally after a few minutes 
of continuous polling and readout of data. It seems like the V792N is hanged 
and a hardware reset of the VME system is required to bring it working again. 
If I do not poll for DREADY first and directly read the Output Buffer 
continuously, the system can work properly.

I have worked on this problem many days but I cannot find any clues to solve 
it. I have tried to use the CAENVMEDemo program (with some modifications) to 
do the same thing (polling and readout) and it works fine. CAEN technical 
support also doesn't know why the VME system is hanged. I think it might be a 
problem of MIDAS itself. I have tried with MIDAS revision 4132 and the trunk 
version, but the problem is still there. Is there any parameter in MIDAS 
(buffer size etc?) which may cause this problem? I have attached my frontend 
code and drivers for your reference.

Thank you for your kind attention.

Best Regards,
Jimmy
Attachment 1: frontend.c  8 kB  | Hide | Hide all | Show all
/********************************************************************\

  Name:         frontend.c
  Created by:   Stefan Ritt
  Modified by:  Jimmy Ngai

  Date:         July 1, 2008

  Contents:     Experiment specific readout code (user part) of
                Midas frontend. This example simulates a "trigger
                event" which are filled with VME data. The trigger
                event is filled with two banks(ADC0 and TDC0).

  $Id: frontend.c 4089 2007-11-27 07:28:17Z ritt@PSI.CH $

\********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "midas.h"
#include "mvmestd.h"
#include "experim.h"

#define HAVE_V792N

/* make frontend functions callable from the C framework */
#ifdef __cplusplus
extern "C" {
#endif

#ifdef HAVE_V792N
#include "vme/v792n.h"
#endif

/*-- Globals -------------------------------------------------------*/

/* The frontend name (client name) as seen by other MIDAS clients   */
char *frontend_name = "Sample Frontend";
/* The frontend file name, don't change it */
char *frontend_file_name = __FILE__;

/* frontend_loop is called periodically if this variable is TRUE    */
BOOL frontend_call_loop = FALSE;

/* a frontend status page is displayed with this frequency in ms */
INT display_period = 3000;

/* maximum event size produced by this frontend */
INT max_event_size = 10000;

/* maximum event size for fragmented events (EQ_FRAGMENTED) */
INT max_event_size_frag = 5 * 1024 * 1024;

/* buffer size to hold events */
INT event_buffer_size = 100 * 10000;

/* Hardware */
MVME_INTERFACE *myvme;

/* VME base address */
DWORD V792N_BASE = 0x32100000;

/* number of channels */
#define N_ADC      16

/*-- Function declarations -----------------------------------------*/

INT frontend_init();
INT frontend_exit();
INT begin_of_run(INT run_number, char *error);
INT end_of_run(INT run_number, char *error);
INT pause_run(INT run_number, char *error);
INT resume_run(INT run_number, char *error);
INT frontend_loop();

INT read_trigger_event(char *pevent, INT off);
INT read_scaler_event(char *pevent, INT off);

/*-- Equipment list ------------------------------------------------*/

EQUIPMENT equipment[] = {

   {"Trigger",               /* equipment name */
    {1, 0,                   /* event ID, trigger mask */
     "SYSTEM",               /* event buffer */
     EQ_POLLED,              /* equipment type */
     LAM_SOURCE(0, 0xFFFFFF),        /* event source crate 0, all stations */
     "MIDAS",                /* format */
     TRUE,                   /* enabled */
     RO_RUNNING,             /* read only when running */
     500,                    /* poll for 500ms */
     0,                      /* stop run after this event limit */
     0,                      /* number of sub events */
     0,                      /* don't log history */
     "", "", "",},
    read_trigger_event,      /* readout routine */
    },

   {""}
};

#ifdef __cplusplus
}
#endif

/********************************************************************\
              Callback routines for system transitions

  These routines are called whenever a system transition like start/
  stop of a run occurs. The routines are called on the following
  occations:

  frontend_init:  When the frontend program is started. This routine
                  should initialize the hardware.

  frontend_exit:  When the frontend program is shut down. Can be used
                  to releas any locked resources like memory, commu-
                  nications ports etc.

  begin_of_run:   When a new run is started. Clear scalers, open
                  rungates, etc.

  end_of_run:     Called on a request to stop a run. Can send
                  end-of-run event and close run gates.

  pause_run:      When a run is paused. Should disable trigger events.

  resume_run:     When a run is resumed. Should enable trigger events.
\********************************************************************/

INT init_vme_modules()
{
#ifdef HAVE_V792N
   v792n_SoftReset(myvme, V792N_BASE);
   v792n_Setup(myvme, V792N_BASE, 3);
//   v792n_Status(myvme, V792N_BASE);
#endif

   return SUCCESS;
}

/*-- Frontend Init -------------------------------------------------*/

INT frontend_init()
{
   int status;

   /* hardware initialization */

   // Open VME interface
   status = mvme_open(&myvme, 0);

   // Set am to A32 non-privileged Data
   mvme_set_am(myvme, MVME_AM_A32_ND);

   // Initialize all VME modules
   init_vme_modules();

   v792n_OfflineSet(myvme, V792N_BASE);
   v792n_DataClear(myvme, V792N_BASE);

   /* print message and return FE_ERR_HW if frontend should not be started */
   if (status != MVME_SUCCESS) {
      cm_msg(MERROR, "frontend_init", "VME interface could not be opened.");
//      return FE_ERR_HW;
   }

   return SUCCESS;
}

/*-- Frontend Exit -------------------------------------------------*/

INT frontend_exit()
{
   // Close VME interface
   mvme_close(myvme);

   return SUCCESS;
}

/*-- Begin of Run --------------------------------------------------*/

INT begin_of_run(INT run_number, char *error)
{
   // Initialize all VME modules
   init_vme_modules();

   v792n_OnlineSet(myvme, V792N_BASE);

   return SUCCESS;
}

/*-- End of Run ----------------------------------------------------*/

INT end_of_run(INT run_number, char *error)
{
   v792n_OfflineSet(myvme, V792N_BASE);
   v792n_DataClear(myvme, V792N_BASE);

   return SUCCESS;
}

/*-- Pause Run -----------------------------------------------------*/

INT pause_run(INT run_number, char *error)
{
   v792n_OfflineSet(myvme, V792N_BASE);

   return SUCCESS;
}

/*-- Resuem Run ----------------------------------------------------*/

INT resume_run(INT run_number, char *error)
{
   v792n_OnlineSet(myvme, V792N_BASE);

   return SUCCESS;
}

/*-- Frontend Loop -------------------------------------------------*/

INT frontend_loop()
{
   /* if frontend_call_loop is true, this routine gets called when
      the frontend is idle or once between every event */
   return SUCCESS;
}

/*------------------------------------------------------------------*/

/********************************************************************\

  Readout routines for different events

\********************************************************************/

/*-- Trigger event routines ----------------------------------------*/

INT poll_event(INT source, INT count, BOOL test)
/* Polling routine for events. Returns TRUE if event
   is available. If test equals TRUE, don't return. The test
   flag is used to time the polling */
{
   int i;
   DWORD lam;

   for (i = 0; i < count; i++) {
      lam = v792n_DataReady(myvme, V792N_BASE);
      if (lam)
         if (!test)
            return TRUE;
   }

   return FALSE;
}

/*-- Interrupt configuration ---------------------------------------*/

INT interrupt_configure(INT cmd, INT source, POINTER_T adr)
{
   switch (cmd) {
   case CMD_INTERRUPT_ENABLE:
      break;
   case CMD_INTERRUPT_DISABLE:
      break;
   case CMD_INTERRUPT_ATTACH:
      break;
   case CMD_INTERRUPT_DETACH:
      break;
   }
   return SUCCESS;
}

/*-- Event readout -------------------------------------------------*/

#ifdef HAVE_V792N
INT read_v792n(INT base, const char *bk_name, char *pevent, INT n_chn)
{
   INT i;
   INT nentry = 0, counter;
   DWORD data[V792N_MAX_CHANNELS+2];
   WORD *pdata;

   // Event counter
//   v792n_EvtCntRead(myvme, base, &counter);

   // Read event
   v792n_EventRead(myvme, base, data, &nentry);

   // Clear ADC
//   v792n_DataClear(myvme, base);

   // Create ADC bank
   bk_create(pevent, bk_name, TID_WORD, &pdata);

   for (i = 0; i < n_chn; i++)
      pdata[i] = 0;

   for (i = 0; i < nentry; i++) {
... 27 more lines ...
Attachment 2: v1718.c  7 kB  | Hide | Hide all | Show all
/********************************************************************

  Name:         v1718.c
  Created by:   Jimmy Ngai

  Contents:     Midas VME standard (MVMESTD) layer for CAEN V1718
                VME-USB2.0 Bridge using CAENVMElib Linux library

  Based on sis3100.c by Stefan Ritt

  $Id: $

\********************************************************************/

#ifdef __linux__
#ifndef OS_LINUX
#define OS_LINUX
#endif
#endif

#ifdef OS_LINUX

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>

#include "CAENVMElib.h"

#endif // OS_LINUX

#include "mvmestd.h"

/*------------------------------------------------------------------*/

int mvme_open(MVME_INTERFACE **vme, int idx)
{
   *vme = (MVME_INTERFACE *) malloc(sizeof(MVME_INTERFACE));
   if (*vme == NULL)
      return MVME_NO_MEM;

   memset(*vme, 0, sizeof(MVME_INTERFACE));

   /* open VME */
   if (CAENVME_Init(cvV1718, 0, idx, &(*vme)->handle) != cvSuccess)
      return MVME_NO_INTERFACE;

   /* default values */
   (*vme)->am        = MVME_AM_DEFAULT;
   (*vme)->dmode     = MVME_DMODE_D32;
   (*vme)->blt_mode  = MVME_BLT_NONE;
   (*vme)->table     = NULL; // not used

   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_close(MVME_INTERFACE *vme)
{
   CAENVME_End(vme->handle);

   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_sysreset(MVME_INTERFACE *vme)
{
   CAENVME_SystemReset(vme->handle);

   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_write(MVME_INTERFACE *vme, mvme_addr_t vme_addr, void *src, mvme_size_t n_bytes)
{
   mvme_size_t n;
   DWORD data;
   int status=0;
   int hvme;
   hvme = vme->handle;

   if (n_bytes <= 4) {
      data = n = 0;
      memcpy(&data, src, n_bytes);

      /* D8 */
      if (vme->dmode == MVME_DMODE_D8)
         status = CAENVME_WriteCycle(hvme, vme_addr, &data, vme->am, cvD8);
      /* D16 */
      else if (vme->dmode == MVME_DMODE_D16)
         status = CAENVME_WriteCycle(hvme, vme_addr, &data, vme->am, cvD16);
      /* D32 */
      else if (vme->dmode == MVME_DMODE_D32)
         status = CAENVME_WriteCycle(hvme, vme_addr, &data, vme->am, cvD32);
      
      if (status == cvSuccess)
         n = n_bytes;
      else
         n = 0;
   } else {

      /* D32 BLT */
      if (vme->blt_mode == MVME_BLT_BLT32)
         status |= CAENVME_BLTWriteCycle(hvme, vme_addr, src, n_bytes, vme->am, cvD32, &n);
      /* D64 MBLT */
      else if (vme->blt_mode == MVME_BLT_MBLT64)
         status |= CAENVME_MBLTWriteCycle(hvme, vme_addr, src, n_bytes, vme->am, &n);

      if (status != cvSuccess)
         n = 0;
   }

   return n;
}

/*------------------------------------------------------------------*/

int mvme_write_value(MVME_INTERFACE *vme, mvme_addr_t vme_addr, unsigned int value)
{
   mvme_size_t n;
   int status=0;
   int hvme;
   hvme = vme->handle;

   if (vme->dmode == MVME_DMODE_D8)
      n = 1;
   else if (vme->dmode == MVME_DMODE_D16)
      n = 2;
   else
      n = 4;

   /* D8 */
   if (vme->dmode == MVME_DMODE_D8)
      status = CAENVME_WriteCycle(hvme, vme_addr, &value, vme->am, cvD8);
   /* D16 */
   else if (vme->dmode == MVME_DMODE_D16)
      status = CAENVME_WriteCycle(hvme, vme_addr, &value, vme->am, cvD16);
   /* D32 */
   else if (vme->dmode == MVME_DMODE_D32)
      status = CAENVME_WriteCycle(hvme, vme_addr, &value, vme->am, cvD32);

   if (status != cvSuccess)
      n = 0;

   return n;
}

/*------------------------------------------------------------------*/

int mvme_read(MVME_INTERFACE *vme, void *dst, mvme_addr_t vme_addr, mvme_size_t n_bytes)
{
   mvme_size_t i, n;
   DWORD data;
   int status=0, cfifo;
   int hvme;
   hvme = vme->handle;

   if (n_bytes <= 4) {
      data = 0;

      /* D8 */
      if (vme->dmode == MVME_DMODE_D8)
         status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD8);
      /* D16 */
      else if (vme->dmode == MVME_DMODE_D16)
         status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD16);
      /* D32 */
      else if (vme->dmode == MVME_DMODE_D32)
         status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD32);
      
      memcpy(dst, &data, n_bytes);
      if (status == cvSuccess)
         n = n_bytes;
      else
         n = 0;

   } else {

      n = 0;

      /* normal I/O */
      if (vme->blt_mode == MVME_BLT_NONE) {
         for (i=0 ; i<n_bytes ; i++)
            status = CAENVME_ReadCycle(hvme, vme_addr, dst+i, vme->am, cvD8);
         n = n_bytes;
      /* D32 BLT */
      } else if (vme->blt_mode == MVME_BLT_BLT32)
         status |= CAENVME_BLTReadCycle(hvme, vme_addr, dst, n_bytes, vme->am, cvD32, &n);
      /* D32 FIFO BLT */
      else if (vme->blt_mode == MVME_BLT_BLT32FIFO) {
         CAENVME_GetFIFOMode(hvme, &cfifo);
         status = CAENVME_SetFIFOMode(hvme, 1);
         status |= CAENVME_BLTReadCycle(hvme, vme_addr, dst, n_bytes, vme->am, cvD32, &n);
         CAENVME_SetFIFOMode(hvme, cfifo);
      /* D64 MBLT */
      } else if (vme->blt_mode == MVME_BLT_MBLT64)
         status |= CAENVME_MBLTReadCycle(hvme, vme_addr, dst, n_bytes, vme->am, &n);
      /* D64 FIFO MBLT */
      else if (vme->blt_mode == MVME_BLT_MBLT64FIFO) {
         CAENVME_GetFIFOMode(hvme, &cfifo);
         status = CAENVME_SetFIFOMode(hvme, 1);
         status |= CAENVME_MBLTReadCycle(hvme, vme_addr, dst, n_bytes, vme->am, &n);
         CAENVME_SetFIFOMode(hvme, cfifo);
      }

      if (status != cvSuccess)
         n = 0;
   }

   return n;
}

/*------------------------------------------------------------------*/

unsigned int mvme_read_value(MVME_INTERFACE *vme, mvme_addr_t vme_addr)
{
   unsigned int data;
   int status=0;
   int hvme;
   hvme = vme->handle;

   data = 0;

   /* D8 */
   if (vme->dmode == MVME_DMODE_D8)
      status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD8);
   /* D16 */
   else if (vme->dmode == MVME_DMODE_D16)
      status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD16);
   /* D32 */
   else if (vme->dmode == MVME_DMODE_D32)
      status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD32);

   return data;
}

/*------------------------------------------------------------------*/

int mvme_set_am(MVME_INTERFACE *vme, int am)
{
   vme->am = am;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_get_am(MVME_INTERFACE *vme, int *am)
{
   *am = vme->am;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_set_dmode(MVME_INTERFACE *vme, int dmode)
{
   vme->dmode = dmode;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_get_dmode(MVME_INTERFACE *vme, int *dmode)
{
   *dmode = vme->dmode;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_set_blt(MVME_INTERFACE *vme, int mode)
{
   vme->blt_mode = mode;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_get_blt(MVME_INTERFACE *vme, int *mode)
{
   *mode = vme->blt_mode;
   return MVME_SUCCESS;
}
Attachment 3: v792n.h  7 kB  | Show | Hide all | Show all
Attachment 4: v792n.c  20 kB  | Show | Hide all | Show all
ELOG V3.1.4-2e1708b5