/***************************************************************************/
/*                                                                         */
/*  Filename: appl_gate_chaining_bank2.c                                   */
/*                                                                         */
/*  Funktion: simple rountine for gate_chaining mode                       */
/*            use only Bank1                                               */
/*                                                                         */
/* 1. Reset SIS330x                                                        */
/* 2. Setup SIS330x                                                        */
/* 3. Readout Loop                                                         */
/* 3.1 Enable Clock to Bank2 (arm)                                         */
/* 3.2 Wait for Bank2 disable Clock to Bank2 (disarm)                      */
/* 3.3 Read and print data (Bank2 event counter,  address counter,         */
/*                          event directory, ADC data)                     */
/*                                                                         */
/* ----------------------------------------------------------------------- */
/*                                                                         */
/*  Autor:                TH                                               */
/*  date:                 24.05.2002                                       */
/*  last modification:    24.05.2002                                       */
/*                                                                         */
/* ----------------------------------------------------------------------- */
/*                                                                         */
/*  SIS  Struck Innovative Systeme GmbH                                    */
/*                                                                         */
/*  Harksheider Str. 102A                                                  */
/*  22399 Hamburg                                                          */
/*                                                                         */
/*  Tel. +49 (0)40 60 87 305 0                                             */
/*  Fax  +49 (0)40 60 87 305 20                                            */
/*                                                                         */
/*  http://www.struck.de                                                   */
/*                                                                         */
/*  © 2002                                                                 */
/*                                                                         */
/***************************************************************************/




#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

#include "dev/pci/sis1100_var.h"
#include "sis3100_vme_calls.h"

#include "../../header/sis3300.h"



int gate_chaining_appl1(int p, u_int32_t vme_base_addr, u_int32_t uint_max_no_events  ) ;


/****************************************************************************/

int main(int argc, char* argv[])
{

#define MAX_NUMBER_LWORDS 0x100000

int p;
int mod_base;

u_int32_t addr ;
u_int32_t data ;

int return_code ;

u_int32_t uint_max_no_events ;


/* open VME */
   if ((p=open("/tmp/sis1100", O_RDWR, 0))<0) {
     printf("error on opening VME environment\n");
     return -1;
   }

if (argc<3)  {
   printf("usage:  SIS330x_VME_BASE_ADDRESS  MAX_NO_OF_EVENTS   \n");
  return -1;
  }

  mod_base           = strtoul(argv[1],NULL,0) ;
  uint_max_no_events = strtoul(argv[2],NULL,0) ;

  addr = mod_base + SIS3300_MODID ;                    /* ID */

  return_code =  vme_A32D32_read(p, addr, &data ) ;
  if (return_code != 0) { printf("vme_A32D32_read:return_code = 0x%08x at addr = 0x%08x\n",return_code,addr); return -1 ;}

  printf("\n");
  printf(" Modul Identification register:  0x%08x\n", data );
  printf("\n");


  return_code = gate_chaining_appl1(p, mod_base, uint_max_no_events ) ;


close(p);
return 0;
}





int gate_chaining_appl1(int p, unsigned int vme_base_addr, unsigned int max_no_events )
{
unsigned int mod_base ;
int no_of_lwords ;

unsigned int addr ;
unsigned int data ;
unsigned int blt_data[MAX_NUMBER_LWORDS] ;
unsigned int get_lwords ;
unsigned int stop_address_pointer ;

int i;

int return_code ;
int error_cnt ;
int loop_cnt ;


mod_base = vme_base_addr ;

/* 1. Reset SIS330x  */
addr = mod_base + SIS3300_KEY_RESET ;                    /* reset */
return_code =  vme_A32D32_write(p, addr, 0x0) ;
if (return_code != 0) {printf("vme_A32D32_write:return_code = 0x%08x at addr = 0x%08x\n",return_code,addr);return -1;}



/* 2. configuartion SIS330x */
data =    ACQ_SET_CLOCK_TO_100MHZ
        + ACQ_ENABLE_MULTI_EVENT_MODE
        + ACQ_ENABLE_LEMO_START_STOP
        + ACQ_ENABLE_GATE_MODE          ;
addr = mod_base + SIS3300_ACQUISTION_CONTROL ; 	/* Acq. register */
return_code =  vme_A32D32_write(p, addr, data) ;
if (return_code != 0) {printf("vme_A32D32_write:return_code = 0x%08x at addr = 0x%08x\n",return_code,addr);return -1;}


data =    CONF_PAGE_SIZE_128K_AUTOSTOP
        + CONF_ENABLE_GATE_CHAINING_MODE   ;

addr = mod_base + SIS3300_EVENT_CONFIG_ALL_ADC ;    /* Event configuration register all ADCs */
return_code =  vme_A32D32_write(p, addr, data) ;
if (return_code != 0) {printf("vme_A32D32_write:return_code = 0x%08x at addr = 0x%08x\n",return_code,addr);return -1;}


addr = mod_base + SIS3300_MAX_NO_OF_EVENTS_ALL_ADC ;    /*  */
return_code =  vme_A32D32_write(p, addr, max_no_events) ;
if (return_code != 0) {printf("vme_A32D32_write:return_code = 0x%08x at addr = 0x%08x\n",return_code,addr);return -1;}




   printf("\n");
   printf("\n");

   loop_cnt = 0;
   error_cnt = 0 ;
   return_code = 0 ;

/* 3. Readout Loop  */
do {

/* 3.1 Enable Clock to Bank2 (arm)  */
   data =  ACQ_ENABLE_CLOCK_TO_BANK2 ; /* ARM_BANK2 */
   addr = mod_base + SIS3300_ACQUISTION_CONTROL ;                    /* Acq. register */
   return_code =  vme_A32D32_write(p, addr, data) ;
   if (return_code != 0) {printf("vme_A32D32_write:return_code = 0x%08x at addr = 0x%08x\n",return_code,addr);return -1;}

   printf("\n");
   printf("\n");
#ifdef print_more
      return_code =  vme_A32D32_read(p, mod_base + SIS3300_CONTROL_STATUS, &data) ;
      printf(" SIS3300_CONTROL_STATUS:  0x%08x\n", data );

      return_code =  vme_A32D32_read(p, mod_base + SIS3300_ACQUISTION_CONTROL, &data) ;
      printf(" SIS3300_ACQUISTION_CONTROL:  0x%08x\n", data );

      return_code =  vme_A32D32_read(p, mod_base + SIS3300_EVENT_CONFIG_ADC12, &data) ;
      printf(" SIS3300_EVENT_CONFIG_ADC12:  0x%08x\n", data );
#endif

/* 3.2 Wait for Bank2 disable Clock to Bank2 (disarm)   */
/* wait for BANK2 to disarm, will happen after max_no_events or if end of memory of Bank2 has been reached */
   do {
      addr = mod_base + SIS3300_ACQUISTION_CONTROL ;                    /* Acq. register */
      return_code =  vme_A32D32_read(p, addr, &data) ;
      if (return_code != 0) { printf("vme_A32D32_read:return_code = 0x%08x at addr = 0x%08x\n",return_code,addr);return -1;}
/*      printf(" Acq. register:  0x%08x\n", data );   */
   } while ((data & ACQ_STATUS_CLOCK_TO_BANK2 ) == ACQ_STATUS_CLOCK_TO_BANK2 ); /*  while ARM  */


/* 3.3 Read data (Bank2 event counter,  address counter, event directory, ADC data)   */

      return_code =  vme_A32D32_read(p, mod_base + SIS3300_BANK2_EVENT_CNT_ADC12, &data) ;
      printf(" SIS3300_BANK2_EVENT_CNT_ADC12:  0x%08x\n", data );
      return_code =  vme_A32D32_read(p, mod_base + SIS3300_BANK2_ADDR_CNT_ADC12, &data) ;
      printf(" SIS3300_BANK2_ADDR_CNT_ADC12:   0x%08x\n", data );
      stop_address_pointer = data ;
      printf("\n");


  /* read Event Directory Bank2 */
      addr = mod_base + SIS3300_EVENT_DIRECTORY_BANK2_ADC12 ;                    /*  Event Directory Bank2 */
      no_of_lwords = max_no_events ;
      return_code =   vme_A32BLT32_read(p, addr, blt_data, no_of_lwords, &get_lwords) ;
      if (get_lwords != no_of_lwords)  {
          printf("get_lwords = 0x%08x\n", get_lwords );
          error_cnt = error_cnt + 1;
        }

   for (i=0;i<no_of_lwords;i++) {
        printf(" SIS3300_EVENT_DIRECTORY_BANK2_ADC12:  i = 0x%08x   blt_data[i] = 0x%08x    End Address = 0x%08x\n", i,
                                                                  blt_data[i], (blt_data[i] -1) );
   }
   printf("\n");


  /* read ADC1/ADC2 datas */
      addr = mod_base + SIS3300_MEMBASE_BANK2_ADC12 ;                    /*  Bank2 */
      no_of_lwords = stop_address_pointer ;
      return_code =   vme_A32BLT32_read(p, addr, blt_data, no_of_lwords, &get_lwords) ;
      if (get_lwords != no_of_lwords) { printf("get_lwords = 0x%08x\n", get_lwords );
          error_cnt = error_cnt + 1;
        }

   for (i=0;i<no_of_lwords;i++) {
        if ((blt_data[i] & SIS3300_GATE_CHAINING_START_BIT) == SIS3300_GATE_CHAINING_START_BIT)  printf("\n");
        printf(" SIS3300_MEMBASE_BANK2_ADC12: i = 0x%08x   blt_data[i] = 0x%08x     ADC1 = 0x%04x   ADC2 = 0x%04x\n", i, blt_data[i],
                                                                    ((blt_data[i] >> 16) & 0xffff), (blt_data[i] & 0xffff)  );
   }

   printf("\n");

   loop_cnt = loop_cnt + 1 ;
/*   if ((loop_cnt & 0xFF) == 0x0 ) */
   {
     printf(" \n");
     printf(" loop counter = 0x%08x \n", loop_cnt);
     printf(" \n");
   }


 }while (return_code == 0);

  return -1 ;
}











































