Back Midas Rome Roody Rootana
  Midas DAQ System  Not logged in ELOG logo
Entry  10 May 2011, Jianglai Liu, Forum, simple example frontend for V1720  
    Reply  10 May 2011, Stefan Ritt, Forum, simple example frontend for V1720  
    Reply  10 May 2011, Pierre-Andre Amaudruz, Forum, simple example frontend for V1720  
       Reply  24 May 2011, Jianglai Liu, Forum, simple example frontend for V1720  v1720.c
    Reply  18 May 2011, Jimmy Ngai, Forum, simple example frontend for V1720  frontend.cv1718.hv1718.cv792n.hv792n.c
       Reply  10 Aug 2012, Carl Blaksley, Forum, simple example frontend for V1720  
          Reply  12 Aug 2012, Jimmy Ngai, Forum, simple example frontend for V1720  Makefile
Message ID: 761     Entry time: 18 May 2011     In reply to: 758     Reply to this: 825
Author: Jimmy Ngai 
Topic: Forum 
Subject: simple example frontend for V1720  

Jianglai Liu wrote:
Hi,

Who has a good example of a frontend program using CAEN V1718 VME-USB bridge and
V1720 FADC? I am trying to set up the DAQ for such a simple system.

I put together a frontend which talks to the VME. However it gets stuck at
"Calibrating" in initialize_equipment().

I'd appreciate some help!

Thanks,
Jianglai


Hi Jianglai,

I don't have an exmaple of using V1718 with V1720, but I have been using V1718 with V792N for a long time.

You may find in the attachment an example frontend program and my drivers for V1718 and V792N written in MVMESTD format. They have to be linked with the CAENVMELib library and other essential MIDAS stuffs.

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

  Name:         frontend.c
  Created by:   Jimmy Ngai

  Date:         May 9, 2010

  Contents:     Experiment specific readout code (user part) of
                Midas frontend.
		Supported VME modules:
		CAEN V1718 VME-USB Bridge
		CAEN V792N 16 CH QDC

  $Id: $

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

#include <stdio.h>
#include <stdlib.h>
#include "midas.h"
#include "mcstd.h"
#include "mvmestd.h"
#include "experim.h"
#include "vme/v792n.h"

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

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

/* The frontend name (client name) as seen by other MIDAS clients   */
char *frontend_name = "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 = 10 * 10000;

/* number of channels */
#define N_ADC      16

/* VME hardware */
MVME_INTERFACE *myvme;

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

/*-- 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);

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

#undef USE_INT

EQUIPMENT equipment[] = {

   {"Trigger",               /* equipment name */
    {1, 0,                   /* event ID, trigger mask */
     "SYSTEM",               /* event buffer */
#ifdef USE_INT
     EQ_INTERRUPT,           /* equipment type */
#else
     EQ_POLLED,              /* equipment type */
#endif
     LAM_SOURCE(CRATE, LAM_STATION(SLOT_ADC)), /* event source */
     "MIDAS",                /* format */
     TRUE,                   /* enabled */
     RO_RUNNING |            /* read only when running */
     RO_ODB,                 /* and update ODB */
     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()
{
   /* default settings */

   v792n_SoftReset(myvme, V792N_BASE);
   v792n_Setup(myvme, V792N_BASE, 2);
//   v792n_Status(myvme, V792N_BASE);

   return SUCCESS;
}

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

INT frontend_init()
{
   INT status;

   /* 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_DataClear(myvme, V792N_BASE);
   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 = 0;

   for (i = 0; i < count; i++) {
      lam = v792n_DataReady(myvme, V792N_BASE);

      if (lam)
         if (!test)
            return lam;
   }

   return 0;
}

/*-- 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 -------------------------------------------------*/

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);

... 29 more lines ...
Attachment 2: v1718.h  3 kB  | Hide | Hide all | Show all
/*********************************************************************

  Name:         v1718.h
  Created by:   Jimmy Ngai

  Contents:     V1718 VME-USB2.0 bridge include

  $Id: $
*********************************************************************/
#ifndef  V1718_INCLUDE_H
#define  V1718_INCLUDE_H

#include <stdio.h>
#include <string.h>
#include "mvmestd.h"

#ifdef __cplusplus
extern "C" {
#endif

#define  V1718_STATUS_RO          (DWORD) (0x0000)
#define  V1718_VME_CTRL_RW        (DWORD) (0x0001)
#define  V1718_FW_REV_RO          (DWORD) (0x0002)
#define  V1718_FW_DWNLD_RW        (DWORD) (0x0003)
#define  V1718_FL_ENA_RW          (DWORD) (0x0004)
#define  V1718_IRQ_STAT_RO        (DWORD) (0x0005)
#define  V1718_IN_REG_RW          (DWORD) (0x0008)
#define  V1718_OUT_REG_S_RW       (DWORD) (0x000A)
#define  V1718_IN_MUX_S_RW        (DWORD) (0x000B)
#define  V1718_OUT_MUX_S_RW       (DWORD) (0x000C)
#define  V1718_LED_POL_S_RW       (DWORD) (0x000D)
#define  V1718_OUT_REG_C_WO       (DWORD) (0x0010)
#define  V1718_IN_MUX_C_WO        (DWORD) (0x0011)
#define  V1718_OUT_MAX_C_WO       (DWORD) (0x0012)
#define  V1718_LED_POL_C_WO       (DWORD) (0x0013)
#define  V1718_PULSEA_0_RW        (DWORD) (0x0016)
#define  V1718_PULSEA_1_RW        (DWORD) (0x0017)
#define  V1718_PULSEB_0_RW        (DWORD) (0x0019)
#define  V1718_PULSEB_1_RW        (DWORD) (0x001A)
#define  V1718_SCALER0_RW         (DWORD) (0x001C)
#define  V1718_SCALER1_RO         (DWORD) (0x001D)
#define  V1718_DISP_ADL_RO        (DWORD) (0x0020)
#define  V1718_DISP_ADH_RO        (DWORD) (0x0021)
#define  V1718_DISP_DTL_RO        (DWORD) (0x0022)
#define  V1718_DISP_DTH_RO        (DWORD) (0x0023)
#define  V1718_DISP_PC1_RO        (DWORD) (0x0024)
#define  V1718_DISP_PC2_RO        (DWORD) (0x0025)
#define  V1718_LM_ADL_RW          (DWORD) (0x0028)
#define  V1718_LM_ADH_RW          (DWORD) (0x0029)
#define  V1718_LM_C_RW            (DWORD) (0x002C)

WORD v1718_Read16(MVME_INTERFACE *mvme, DWORD base, int offset);
void v1718_Write16(MVME_INTERFACE *mvme, DWORD base, int offset, WORD value);
DWORD v1718_Read32(MVME_INTERFACE *mvme, DWORD base, int offset);
void v1718_Write32(MVME_INTERFACE *mvme, DWORD base, int offset, DWORD value);

void v1718_MultiRead(MVME_INTERFACE *mvme, DWORD *addrs, DWORD *value, int ncycle, int *am, int *dmode);
void v1718_MultiWrite(MVME_INTERFACE *mvme, DWORD *addrs, DWORD *value, int ncycle, int *am, int *dmode);
void v1718_MultiRead16(MVME_INTERFACE *mvme, DWORD *addrs, WORD *value, int ncycle);
void v1718_MultiWrite16(MVME_INTERFACE *mvme, DWORD *addrs, WORD *value, int ncycle);
void v1718_MultiRead32(MVME_INTERFACE *mvme, DWORD *addrs, DWORD *value, int ncycle);
void v1718_MultiWrite32(MVME_INTERFACE *mvme, DWORD *addrs, DWORD *value, int ncycle);

void v1718_PulserConfSet(MVME_INTERFACE *mvme, WORD pulser, DWORD period, DWORD width, WORD pulseNo);
void v1718_PulserStart(MVME_INTERFACE *mvme, WORD pulser);
void v1718_PulserStop(MVME_INTERFACE *mvme, WORD pulser);

  enum v1718_PulserSelect {
    v1718_pulserA=0x0,
    v1718_pulserB=0x1,
  };

#ifdef __cplusplus
}
#endif

#endif // V1718_INCLUDE_H

/* emacs
 * Local Variables:
 * mode:C
 * mode:font-lock
 * tab-width: 8
 * c-basic-offset: 2
 * End:
 */
Attachment 3: v1718.c  16 kB  | Show | Hide all | Show all
Attachment 4: v792n.h  7 kB  | Show | Hide all | Show all
Attachment 5: v792n.c  20 kB  | Hide | Hide all | Show all
/*********************************************************************

  Name:         v792n.c
  Created by:   Jimmy Ngai

  Contents:     V792N 16ch. QDC

  Based on v792.c by Pierre-Andre Amaudruz
                
  $Id: $
*********************************************************************/
#include <stdio.h>
#include <string.h>
#include <signal.h>
#if defined(OS_LINUX)
#include <unistd.h>
#endif
#include "v792n.h"

WORD v792n_Read16(MVME_INTERFACE *mvme, DWORD base, int offset)
{
  int cmode;
  WORD data;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  data = mvme_read_value(mvme, base+offset);
  mvme_set_dmode(mvme, cmode);
  return data;
}

void v792n_Write16(MVME_INTERFACE *mvme, DWORD base, int offset, WORD value)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+offset, value);
  mvme_set_dmode(mvme, cmode);
}

DWORD v792n_Read32(MVME_INTERFACE *mvme, DWORD base, int offset)
{
  int cmode;
  DWORD data;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D32);
  data = mvme_read_value(mvme, base+offset);
  mvme_set_dmode(mvme, cmode);
  return data;
}

void v792n_Write32(MVME_INTERFACE *mvme, DWORD base, int offset, DWORD value)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D32);
  mvme_write_value(mvme, base+offset, value);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
int v792n_DataReady(MVME_INTERFACE *mvme, DWORD base)
{
  int data_ready, cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  data_ready = mvme_read_value(mvme, base+V792N_CSR1_RO) & 0x1;
  mvme_set_dmode(mvme, cmode);
  return data_ready;
}

/*****************************************************************/
int v792n_isEvtReady(MVME_INTERFACE *mvme, DWORD base)
{
  int csr;
  csr = v792n_CSR1Read(mvme, base);
  return (csr & 0x100);
}

/*****************************************************************/
int v792n_isBusy(MVME_INTERFACE *mvme, DWORD base)
{
  int status, busy, timeout, cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  timeout = 1000;
  do {
    status = mvme_read_value(mvme, base+V792N_CSR1_RO);
    busy = status & 0x4;
    timeout--;
  } while (busy || timeout);
  mvme_set_dmode(mvme, cmode);
  return (busy != 0 ? 1 : 0);
}

/*****************************************************************/
/*
Read single event, return event length (number of entries)
*/
int v792n_EventRead(MVME_INTERFACE *mvme, DWORD base, DWORD *pdest, int *nentry)
{
#define USE_BLT_READ_2

#ifdef USE_SINGLE_READ
  DWORD hdata;
  int   cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D32);

  *nentry = 0;
  if (v792n_DataReady(mvme, base)) {
    do {
      hdata = mvme_read_value(mvme, base);
    } while (!(hdata & 0x02000000)); // skip up to the header

    pdest[*nentry] = hdata;
    *nentry += 1;
    do {
      pdest[*nentry] = mvme_read_value(mvme, base);
      *nentry += 1;
    } while (!(pdest[*nentry-1] & 0x04000000)); // copy until the trailer

    nentry--;
  }

  mvme_set_dmode(mvme, cmode);
#endif // USE_SINGLE_READ

#ifdef USE_BLT_READ_1
  DWORD hdata, data[V792N_MAX_CHANNELS+2];
  int   cam, cmode, cblt, cnt, i;

  mvme_get_am(mvme, &cam);
  mvme_get_dmode(mvme, &cmode);
  mvme_get_blt(mvme, &cblt);
  mvme_set_dmode(mvme, MVME_DMODE_D32);

  *nentry = 0;
  if (v792n_DataReady(mvme, base)) {
    do {
      hdata = mvme_read_value(mvme, base);
    } while (!(hdata & 0x02000000)); // skip up to the header

    mvme_set_am(mvme, MVME_AM_A32_SB);
    mvme_set_blt(mvme, MVME_BLT_BLT32);
    cnt = (hdata >> 8) & 0x3F;

    mvme_read(mvme, data, base, (cnt+1)*4);
    pdest[0] = hdata;
    for (i=1;i<=cnt+1;i++)
      pdest[i] = data[i-1];

    *nentry = cnt + 2;
  }

  mvme_set_am(mvme, cam);
  mvme_set_dmode(mvme, cmode);
  mvme_set_blt(mvme, cblt);
#endif // USE_BLT_READ_1

#ifdef USE_BLT_READ_2
  int   cam, cmode, cblt, cnt;

  mvme_get_am(mvme, &cam);
  mvme_get_dmode(mvme, &cmode);
  mvme_get_blt(mvme, &cblt);
  mvme_set_dmode(mvme, MVME_DMODE_D32);

  *nentry = 0;
//  if (v792n_DataReady(mvme, base)) {
    mvme_set_am(mvme, MVME_AM_A32_SB);
    mvme_set_blt(mvme, MVME_BLT_BLT32);
    mvme_read(mvme, pdest, base, (V792N_MAX_CHANNELS+2)*4);
    cnt = (pdest[0] >> 8) & 0x3F;
    *nentry = cnt + 2;
//  }

  mvme_set_am(mvme, cam);
  mvme_set_dmode(mvme, cmode);
  mvme_set_blt(mvme, cblt);
#endif //USE_BLT_READ_2

  return *nentry;
}

/*****************************************************************/
/*
Read nentry of data from the data buffer
*/
int v792n_DataRead(MVME_INTERFACE *mvme, DWORD base, DWORD *pdest, int nentry)
{
  int  cmode, status;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D32);
//  nentry = 128;
  if (v792n_DataReady(mvme, base)) {
    status = mvme_read(mvme, pdest, base, nentry*4);
  }
  mvme_set_dmode(mvme, cmode);
  return status;
}

/*****************************************************************/
void v792n_DataClear(MVME_INTERFACE *mvme, DWORD base)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_BIT_SET2_RW, 0x4);
  mvme_write_value(mvme, base+V792N_BIT_CLEAR2_WO, 0x4);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_EvtCntRead(MVME_INTERFACE *mvme, DWORD base, DWORD *evtcnt)
{
  int cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  *evtcnt  = mvme_read_value(mvme, base+V792N_EVT_CNT_L_RO);
  *evtcnt += (mvme_read_value(mvme, base+V792N_EVT_CNT_H_RO) << 16);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_EvtCntReset(MVME_INTERFACE *mvme, DWORD base)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_EVT_CNT_RST_WO, 1);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_IntSet(MVME_INTERFACE *mvme, DWORD base, int level, int vector)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_INT_VECTOR_WO, (vector & 0xFF));
  mvme_write_value(mvme, base+V792N_INT_LEVEL_WO, (level & 0x7));
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_IntEnable(MVME_INTERFACE *mvme, DWORD base, int level)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_EVTRIG_REG_RW, (level & 0x1F));
  /* Use the trigger buffer for int enable/disable
  mvme_write_value(mvme, base+V792N_INT_LEVEL_WO, (level & 0x7));
  */
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_IntDisable(MVME_INTERFACE *mvme, DWORD base)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_EVTRIG_REG_RW, 0);
  /* Use the trigger buffer for int enable/disable
     Setting a level 0 reboot the VMIC !
  mvme_write_value(mvme, base+V792N_INT_LEVEL_WO, 0);
  */
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_EvtTriggerSet(MVME_INTERFACE *mvme, DWORD base, int count)
{
  int cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_EVTRIG_REG_RW, (count & 0x1F));
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_SingleShotReset(MVME_INTERFACE *mvme, DWORD base)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_SINGLE_RST_WO, 1);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
... 409 more lines ...
ELOG V3.1.4-2e1708b5