V1495Lib.c

From New IAC Wiki
Revision as of 22:36, 24 June 2009 by Oborn (talk | contribs) (Created page with '<pre> /* v1495Lib.c - CAEN v1495 logic unit library + VFAT user interface library -------------------------------------------------------------------------- ...')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

/* v1495Lib.c - CAEN v1495 logic unit library + VFAT user interface library



    --------------------------------------------------------------------------

                   --- CAEN SpA - Front End Electronics  ---

    --------------------------------------------------------------------------

    Name        :   V1495Upgrade.c

    Project     :   V1495Upgrade

    Description :   V1495 Upgrade Software


	  This program writes the configuration file (Altera RBF Format) into the
	  flash memory of the Module V1495. This allows to upgrade the firmware
	  for either the VME_INT and the USER fpga from the VME.
	  The program is based on the CAEN Bridge (V1718 or V2718).
	  The software can be compiled for other VME CPUs, changing the functions
      in the custom VME functions (VME_Init(),VME_Write(), VME_Read()).
      Comment away CAENVMElib.h include in this case.

    Date        :   March 2006
    Release     :   1.0
    Author      :   C.Tintori

    --------------------------------------------------------------------------


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

/*

  Revision History:
  1.0    CT     First release
  1.1    LC     USER Flash page map changed. Only STD update allowed.

Adjustment for Motorola VME controllers: Sergey Boyarinov April 23 2007

*/
/*

  example:

download module
ld < /usr/local/clas/devel/coda/src/rol/VXWORKS_ppc/obj/v1495.o

goto directory where your firmware is stored
cd "/usr/local/clas/devel/coda/src/rol/code.s"

download user firmware
v1495firmware(0xfa510000,"v1495USER1.0.rbf",0,0)

download VME firmware (BE CAREFUL !!!)
v1495firmware(0xfa510000,"v1495V2LB_rev03_build_8321.rbf",0,1)


*/




#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <vxWorks.h>
#include <stdioLib.h>
#include <usrLib.h>
#include <taskLib.h>
#include <semLib.h>
#include <intLib.h>
#include <cacheLib.h>
#include <iv.h>
#include <math.h>

#include "v1495Lib.h"



/*sergey*/
#define EIEIO    __asm__ volatile ("eieio")
#define SYNC     __asm__ volatile ("sync")

/* Parameters for the access to the Flash Memory */
#define VME_FIRST_PAGE_STD    768    /* first page of the image STD */
#define VME_FIRST_PAGE_BCK    1408   /* first page of the image BCK */
#define USR_FIRST_PAGE_STD    48     /* first page of the image STD */
#define USR_FIRST_PAGE_BCK    1048   /* first page of the image BCK */
#define PAGE_SIZE       264 /* Number of bytes per page in the target flash */

/* flash memory Opcodes */
#define MAIN_MEM_PAGE_READ          0x00D2
#define MAIN_MEM_PAGE_PROG_TH_BUF1  0x0082






//#define EIEIO()				__asm__ volatile("eieio")
//#define SYNC()				__asm__ volatile("sync")

#define SYSTIME_TO_MS(t)	((t)*60/1000000)
#define SYSTIME_TO_US(t)	((t)*60/1000)
#define NUM_VFATS		6


#define NUM_WORDS		14 // these are the number of words in the V1495ReadoutStatus struct
typedef struct
{
	volatile unsigned int TotalBytes;
	volatile unsigned int TotalFrames;
	volatile unsigned int DeltaBytes;
	volatile unsigned int DeltaFrames;
	volatile unsigned int LastSize;
	volatile unsigned int LengthDataFIFO;
	volatile unsigned int LengthSizeFIFO;
	volatile unsigned int Sent;
	volatile unsigned short LastCapture[12];
} V1495ReadoutStatus;


//volatile UINT32 practiceArray[168];

/* Define Global structs */
volatile V1495ReadoutCtrlRegs * v1495;
volatile V1495ReadoutStatus v1495Channels[6];



// Binary codes
/*
const unsigned int START_FILE  = 0x1A02C741;        // Start File 
const unsigned int END_FILE    = 0x05C12170;        // End File
const unsigned int FILE_INFO   = 0x10B22EAB;        // File Info
const unsigned int START_EVENT = 0xE1AC021D;        // Start Event
const unsigned int END_EVENT   = 0x14173aAD;        // End Event 
const unsigned short int ZERO  = 0x0000;            // Zero for padding

FILE *bin_file;
unsigned int file_num = 1;

*/


/****************************************************************************
 write_flash_page
    flag=0 for USER flash (default)
        =1 for VME flash
****************************************************************************/
int
write_flash_page1(unsigned int addr, unsigned char *page, int pagenum, int flag)
{
  volatile V1495 *v1495 = (V1495 *) addr;
  int i, flash_addr, data;
  unsigned char addr0, addr1, addr2;
  int res = 0;
  unsigned short *Sel_Flash; /* VME Address of the FLASH SELECTION REGISTER */
  unsigned short *RW_Flash;  /* VME Address of the FLASH Read/Write REGISTER */

  if(flag==1)
  {
    Sel_Flash = (short *)&(v1495->selflashVME);
    RW_Flash = (short *)&(v1495->flashVME);
  }
  else
  {
    Sel_Flash = (short *)&(v1495->selflashUSER);
    RW_Flash = (short *)&(v1495->flashUSER);
  }

  EIEIO;
  SYNC;
  flash_addr = pagenum << 9;
  addr0 = (unsigned char)flash_addr;
  addr1 = (unsigned char)(flash_addr>>8);
  addr2 = (unsigned char)(flash_addr>>16);

  EIEIO;
  SYNC;
  /* enable flash (NCS = 0) */
  data = 0;
  *Sel_Flash = data;

  EIEIO;
  SYNC;
  /* write opcode */
  data = MAIN_MEM_PAGE_PROG_TH_BUF1;
  *RW_Flash = data;

  EIEIO;
  SYNC;
  /* write address */
  data = addr2;
  *RW_Flash = data;
  data = addr1;
  *RW_Flash = data;
  data = addr0;
  *RW_Flash = data;

  EIEIO;
  SYNC;
  /* write flash page */
  for(i=0; i<PAGE_SIZE; i++)
  {
    data = page[i];
    *RW_Flash = data;
  }

  EIEIO;
  SYNC;
  /* wait 20ms (max time required by the flash to complete the writing) */
  taskDelay(10); /* 1 tick = 10ms */

  EIEIO;
  SYNC;
  /* disable flash (NCS = 1) */
  data = 1;
  *Sel_Flash = data;


  EIEIO;
  SYNC;
  /* wait 20ms (max time required by the flash to complete the writing) */
  taskDelay(20);
  EIEIO;
  SYNC;

  return(res);
}

/****************************************************************************
 read_flash_page
****************************************************************************/
int
read_flash_page1(unsigned int addr, unsigned char *page, int pagenum, int flag)
{
  volatile V1495 *v1495 = (V1495 *) addr;
  int i, flash_addr, data;
  /*volatile*/ unsigned short data16;
  unsigned char addr0,addr1,addr2;
  int res = 0;
  unsigned short *Sel_Flash; /* VME Address of the FLASH SELECTION REGISTER */
  unsigned short *RW_Flash;  /* VME Address of the FLASH Read/Write REGISTER */

  if(flag==1)
  {
    Sel_Flash = (short *)&(v1495->selflashVME);
    RW_Flash = (short *)&(v1495->flashVME);
  }
  else
  {
    Sel_Flash = (short *)&(v1495->selflashUSER);
    RW_Flash = (short *)&(v1495->flashUSER);
  }

  EIEIO;
  SYNC;
  flash_addr = pagenum << 9;
  addr0 = (unsigned char)flash_addr;
  addr1 = (unsigned char)(flash_addr>>8);
  addr2 = (unsigned char)(flash_addr>>16);

  EIEIO;
  SYNC;
  /* enable flash (NCS = 0) */
  data = 0;
  *Sel_Flash = data;


  EIEIO;
  SYNC;
  /* write opcode */
  data = MAIN_MEM_PAGE_READ;
  *RW_Flash = data;



  EIEIO;
  SYNC;
  /* write address */
  data = addr2;
  *RW_Flash = data;
  data = addr1;
  *RW_Flash = data;
  data = addr0;
  *RW_Flash = data;


  EIEIO;
  SYNC;
  /* additional don't care bytes */
  data = 0;
  for(i=0; i<4; i++)
  {
    *RW_Flash = data;
  }

  EIEIO;
  SYNC;
  /* read flash page */
  for(i=0; i<PAGE_SIZE; i++)
  {
    data16 = *RW_Flash;
    page[i] = (unsigned char)data16;
  }
  EIEIO;
  SYNC;

  /* disable flash (NCS = 1) */
  data = 1;
  *Sel_Flash = data;
  EIEIO;
  SYNC;

  return(res);
}


int
v1495test(unsigned int baseaddr)
{
  // the address location below starts at the USER FPGA access location which is 
  //0x8000 lower in memory than the dial switches for the module address location.

  // if SW3=0 SW4=8 SW7=1 SW8=1 => 0x80118000 is the 32 bit address and 0x90118000 is the 24 bit adresss

  // then try v1495test(0x80110000)
  volatile V1495 *v1495 = (V1495 *) baseaddr;
  unsigned short *data16 = (unsigned short *)&(v1495->control);

  printf("Control      [0x%08x] = 0x%04x\n",&(v1495->control),v1495->control);
  printf("firmwareRev  [0x%08x] = 0x%04x\n",&(v1495->firmwareRev),v1495->firmwareRev);
  printf("selflashVME  [0x%08x] = 0x%04x\n",&(v1495->selflashVME),v1495->selflashVME);
  printf("flashVME     [0x%08x] = 0x%04x\n",&(v1495->flashVME),v1495->flashVME);
  printf("selflashUSER [0x%08x] = 0x%04x\n",&(v1495->selflashUSER),v1495->selflashUSER);
  printf("flashUSER    [0x%08x] = 0x%04x\n",&(v1495->flashUSER),v1495->flashUSER);
  printf("configROM    [0x%08x] = 0x%04x\n",&(v1495->configROM[0]),v1495->configROM[0]);

  return(0);
}

int
v1495test1()
{
  volatile V1495 *v1495 = (V1495 *) 0x80110000;
  unsigned short *data16 = (unsigned short *)&(v1495->control);

  printf("Control      [0x%08x] = 0x%04x\n",&(v1495->control),v1495->control);
  printf("firmwareRev  [0x%08x] = 0x%04x\n",&(v1495->firmwareRev),v1495->firmwareRev);
  printf("selflashVME  [0x%08x] = 0x%04x\n",&(v1495->selflashVME),v1495->selflashVME);
  printf("flashVME     [0x%08x] = 0x%04x\n",&(v1495->flashVME),v1495->flashVME);
  printf("selflashUSER [0x%08x] = 0x%04x\n",&(v1495->selflashUSER),v1495->selflashUSER);
  printf("flashUSER    [0x%08x] = 0x%04x\n",&(v1495->flashUSER),v1495->flashUSER);
  printf("configROM    [0x%08x] = 0x%04x\n",&(v1495->configROM[0]),v1495->configROM[0]);

  return(0);
}

/*int
v1495reload()
{
  volatile V1495 *v1495 = (V1495 *)0xfa510000;
  unsigned short *Conf_Flash;
  Conf_Flash = (short *)&(v1495->configUSER);

  printf("Reloading user FPGA firmware...");

  EIEIO;
  SYNC;
  *Conf_Flash = 1;
  EIEIO;
  SYNC;

  printf("done!\n");

  return 0;
}*/

int
v1495reload(unsigned int baseaddr)
{
  volatile V1495 *v1495 = (V1495 *)baseaddr;
  unsigned short *Conf_Flash;
  Conf_Flash = (short *)&(v1495->configUSER);

  printf("Reloading user FPGA firmware...");

  EIEIO;
  SYNC;
  *Conf_Flash = 1;
  EIEIO;
  SYNC;

  printf("done!\n");

  return 0;
}


/*****************************************************************************
   MAIN

     baseaddr: full board address (for example 0x80510000)
     filename: RBF file name
     page: =0 for standard, =1 for backup
     user_vme: Firmware to update selector = 0 => USER, 1 => VME

*****************************************************************************/
int
v1495firmware(unsigned int baseaddr, char *filename, int page, int user_vme)
{
  int finish,i;
  int bp, bcnt, pa;
  char c;
  unsigned char pdw[PAGE_SIZE], pdr[PAGE_SIZE];
  unsigned long vboard_base_address;
  FILE *cf;

  /*page = 0;     ONLY STD !!!!!!!!!!!!! */
  /*user_vme = 0; ONLY USER !!!!!!!!!!!! */

  printf("\n");
  printf("********************************************************\n");
  printf("* CAEN SpA - Front-End Division                        *\n");
  printf("* ---------------------------------------------------- *\n");
  printf("* Firmware Upgrade of the V1495                        *\n");
  printf("* Version 1.1 (27/07/06)                               *\n");
  printf("*   Sergey Boyarinov: CLAS version 23-Apr-2007         *\n");
  printf("********************************************************\n\n");

  /* open the configuration file */
  cf = fopen(filename,"rb");
  if(cf==NULL)
  {
    printf("\n\nCan't open v1495 firmware file >%s< - exit\n",filename);
    exit(1);
  }

  if(user_vme == 0) /* FPGA "User" */
  {
    if(page == 0)
    {
      pa = USR_FIRST_PAGE_STD;
    }
    else if(page == 1)
    {
      printf("Backup image not supported for USER FPGA\n");
      exit(0);
	}
    else
    {
      printf("Bad Image.\n");
	  exit(0);
    }

    printf("Updating firmware of the FPGA USER with the file %s\n",filename);
  }
  else if(user_vme == 1) /* FPGA "VME_Interface" */
  {
    if(page == 0)
    {
      printf("Writing STD page of the VME FPGA\n");
      pa = VME_FIRST_PAGE_STD;
	}
    else if(page == 1)
    {
      printf("Writing BCK page of the VME FPGA\n");
      pa = VME_FIRST_PAGE_BCK;
	}
    else
    {
      printf("Bad Image.\n");
      exit(0);
	}

    printf("Updating firmware of the FPGA VME with the file %s\n", filename);
  }
  else
  {
    printf("Bad FPGA Target.\n");
	exit(0);
  }


  bcnt = 0; /* byte counter */
  bp = 0;   /* byte pointer in the page */
  finish = 0;

  /* while loop */
  while(!finish)
  {
    c = (unsigned char) fgetc(cf); /* read one byte from file */

    /* mirror byte (lsb becomes msb) */
    pdw[bp] = 0;
    for(i=0; i<8; i++)
    {
	if(c & (1<<i))
	{
        pdw[bp] = pdw[bp] | (0x80>>i);
	}
    }

    bp++;
    bcnt++;
    if(feof(cf))
    {
      printf("End of file: bp=%d bcnt=%d\n",bp,bcnt);
      finish = 1;
    }

    /* write and verify a page */
    if((bp == PAGE_SIZE) || finish)
    {
      write_flash_page1(baseaddr, pdw, pa, user_vme);
      read_flash_page1(baseaddr, pdr, pa, user_vme);
      for(i=0; i<PAGE_SIZE; i++)
      {
        if(pdr[i] != pdw[i])
        {
          printf("[%3d] written 0x%02x, read back 0x%02x",i,pdw[i],pdr[i]);
          printf(" -> Flash writing failure (byte %d of page %d)!\n",i,pa);
          printf("\nFirmware not loaded !\n");
          exit(0);
        }
	  }
      bp=0;
      pa++;
    }
  } /* end of while loop */

  fclose(cf);
  printf("\nFirmware loaded successfully. Written %d bytes\n", bcnt);
//  printf("Write 1 at address 0x8016 to reload updated version of the User FPGA\n");

  printf("\n");
  v1495reload(baseaddr);

  return(0);
}


//<---------- Old v1495ReadoutCtrl.c


/*
void
v1495CRCCalc(void)
{
	int i, nShorts = 12, nShifts = 16;

	USHORT Message[12] = { 0xABFF, 0xC100, 0xE6EC, 0x0000, 0x0000, 0x0000, 0x0000,
				0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };

	USHORT result, Poly = 0x8811, CRC = 0x291A;

	result = CRC;
	for(i=0;i<nShorts;i++)
	{
		for(j=0;j<nShifts;j++)
		{
			result = (Poly|result)^(Message[i]<<j);		
		}
	}

	if(result == CRC)
		printf("Your checksum matches\n");
	else
		printf("Your checksum does not match\n");

	return;
}
*/

/*
void
v1495ResetPractice(void)
{
	int i;

	for(i=0;i<14*NUM_VFATS;i++)
		practiceArray[i] = i;

	return;
}
*/
/*
void
v1495ReadOutPractice(void)
{
	int i, j;

	printf("practiceArray addr: 0x%04X \n",practiceArray);

	for(i=0;i<NUM_VFATS;i++)
	{
		for(j=0;j<4;j++)
				printf("%08X ", practiceArray[14*i+j]);

		printf("\n");

		for(j;j<8;j++)
				printf("%08X ", practiceArray[14*i+j]);

		printf("\n");

		for(j;j<14;j++)
			printf("%08X ", practiceArray[14*i+j]);

		printf("\n\n");
	}
	return;
}
*/

void
v1495Release(void)
{
	v1495 = NULL;

	return;
}

int
v1495DataReady(void)
{
	int i, FIFOBigSize = 0, EventBigSize = 0;

	if(v1495 == NULL) {
    		printf("v1495Sprint: ERROR : v1495 not initialized \n");
    		return(-1);
  	}

	for(i=0;i<NUM_VFATS;i++)
		if(FIFOBigSize < (v1495->FIFOLength[i])& 0x3F)
			FIFOBigSize = v1495->FIFOLength[i]&0x3F;
/*
	for(i=0;i<6;i++)
		if(v1495->EventsSentH[i] || EventBigSize < v1495->EventsSentL[i])
			EventBigSize = v1495->EventsSentL[i];
	
	
	if(FIFOBigSize != EventBigSize)
	{
		printf("v1495DataReady: Error: Number of words in sizeFIFO does not equal EventSize.\n");
		return(ERROR);
	}
*/
	return FIFOBigSize;
}


STATUS
v1495Sprint(void) // this function prints out myfav registers
{
	
	int i;
	unsigned short NumData, NumSize;


	if(v1495 == NULL) {
    		printf("v1495Sprint: ERROR : v1495 not initialized \n");
    		return(-1);
  	}
	
	for(i=0;i<NUM_VFATS;i++)
	{
		NumData = (v1495->FIFOLength[i]>>6) & FIFO_WORDS_MASK;
		NumSize = v1495->FIFOLength[i] & FIFO_WORDS_MASK;

		//printf("A0_FIFOSIZE Addr: 0x%08x Data: 0x%04x \n",&(v1495->FIFOLength[0]),v1495->FIFOLength[0]);
		printf("Number of words in GEM[%i]dataFIFO : %04u, 0x%04X \n",i,NumData,NumData);	
		printf("Number of words in GEM[%i]sizeFIFO : %04u \n",i,NumSize);
	
		printf("GEM[%i]_EVENTSSENTH Addr: 0x%08x Data: 0x%04x \n"
			,i,&(v1495->EventsSentH[i]),v1495->EventsSentH[i]);
		printf("GEM[%i]_EVENTSSENTL Addr: 0x%08x Data: 0x%04x \n"
			,i,&(v1495->EventsSentL[i]),v1495->EventsSentL[i]);
		printf("\n");
	
	}
	
	
	printf("\n");

	return(OK);
}

STATUS
v1495Reset(void)
{
	int i;

	if(v1495 == NULL) {
    		printf("v1495Reset: ERROR : v1495 not initialized \n");
    		return(-1);
  	}	

	v1495->Reset = 0;

	printf("v1495 module has been reset: \n\n");


	//v1495Sprint();

	/*
	for(i=0;i<NUM_VFATS;i++) {
		if(v1495->EventsSentH[i] > 0 || v1495->EventsSentL[i] > 0)
			printf("GEM[%i] is not present. EventsSentL:0x%04X\n",i,v1495->EventsSentL[i]);
		else if (v1495->EventsSentL[i] == 0)
			printf("GEM[%i] is present. \n",i);
		else
			printf("v1495Reset: ERROR: GEM[%i] has reported invalid value for .EventsSentL 					\n",i);	
	}

	printf("\n");
	*/

	return(OK);
}

STATUS 
v1495Init(UINT32 Addr)
{
	UINT32 laddr;
	USHORT  boardID = 0;
	UCHAR BIDH, BIDL;
	int res, rdata; 


	/* A32 Addressing */

#ifdef VXWORKS68K51
	printf("v1495Init: ERROR: 68K Based CPU cannot support A32 addressing (use A24)\n");
    	return(ERROR);
#endif

    	/* get the v1495 address */
	res = sysBusToLocalAdrs(0x09,(char *)Addr,(char **)&laddr);
    	if (res != 0) {
		printf("v1495Init: ERROR in sysBusToLocalAdrs(0x09,0x%x,&laddr) \n",Addr);
	return(ERROR);
    	}
    	//cv1495MemOffset = laddr - addr;
	v1495 = (V1495ReadoutCtrlRegs *) laddr;
	
	
      	/* Check if Board exists at that address */
    	res = vxMemProbe((char *) v1495,0,2,(char *)&rdata);
    	if(res < 0) {	
		printf("c1495Init: ERROR: No addressable board at addr=0x%x\n",(UINT32) v1495);
		v1495 = NULL;
		return(ERROR);
	} else {
      	/* Check if this is a Model v1495 */
      		BIDH = *((UCHAR *)v1495 + BOARD_ID_OFFSET_H);
		BIDL = *((UCHAR *)v1495 + BOARD_ID_OFFSET_L);
	      	boardID = BIDH<<8 | BIDL;
	      	if(boardID != V1495_BOARD_ID) {
			printf(" ERROR: Board ID 0x%X does not match 0x%04X \n",V1495_BOARD_ID, boardID);
			printf(" BIDH: 0x%X ; BIDL: 0x%X \n",BIDH, BIDL);
			return(ERROR);
	      	}
	}    	
    	
	printf("v1495Init: v1495 Module has been successfully initialized.\n\n",BIDH, BIDL);

	/* Disable/Clear v1495 */
	v1495Reset();
		
	return(OK);
}

// takes in one Hex word and converts it to four Hex words representing binary
void 
v1495HextoBin(USHORT LastCapture, USHORT * HextoBin)
{
	USHORT i, j, shift, temp[4] = {0x11,0x10,0x01,0x00};

//	printf("\nReceived 0x%04X : \n", LastCapture);

	for(i=0;i<4;i++) {
		shift = i<<2; 
		temp[i] = (LastCapture & (0xF000 >> (shift))) >> (12-shift);
	}

	for(i=0;i<4;i++) 	{
		for(j=0;j<4;j++)
			temp[i] |= (temp[i]&(0x1<<(3-j)))<<(3*(3-j));
		temp[i] &= 0xFFF1;
	}

	for(i=0;i<4;i++)
		HextoBin[i] = temp[i];

	return;
}


int
v1495ReadEvent(void)
{
	int i, j, k, m, nWords = NUM_WORDS*NUM_VFATS; 
	UINT32 fifo_len[NUM_VFATS], dCnt;
	unsigned short NumData = 0, ChannelsNum[2];
	UCHAR HeaderOK = 1, Header[3] = {0xA, 0xC, 0xE};
	USHORT HextoBin[4] = {0x0000, 0x0001, 0x0010, 0x0011};
	//volatile unsigned short * p;
	//UINT32 Addr = 0x80110000;
	
	if(v1495 == NULL) {
    		printf("v1495ReadEvent: ERROR : v1495 not initialized \n");
    		return(ERROR);
  	}
	
	// Check to see if there are any words stored in any of the dataFIFOs
	for(i=0;i<NUM_VFATS;i++)
	{
		fifo_len[i] = (v1495->FIFOLength[i]>>6) & FIFO_WORDS_MASK;
		NumData |= fifo_len[i];
	}


	if(NumData)
	{
		
		for(i=0;i<NUM_VFATS;i++) // Initialize v1495Channels members to 0.
		{
			v1495Channels[i].TotalBytes = 0;
			v1495Channels[i].TotalFrames = 0;
			v1495Channels[i].DeltaBytes = 0;
			v1495Channels[i].DeltaFrames = 0;
			v1495Channels[i].LastSize = 0;
			v1495Channels[i].LengthSizeFIFO = 0;
			v1495Channels[i].LengthDataFIFO = 0;
			v1495Channels[i].Sent = 0;
			for(j=0;j<12;j++)
				v1495Channels[i].LastCapture[j] = 0;
		}

		for(i=0;i<NUM_VFATS;i++)
		{
			
			if(!v1495Channels[i].LengthDataFIFO)
			{
				v1495Channels[i].LengthSizeFIFO = v1495->FIFOLength[i] & FIFO_WORDS_MASK;
				v1495Channels[i].LengthDataFIFO = fifo_len[i];
			}
			if(v1495Channels[i].LengthDataFIFO)
			{
				v1495Channels[i].Sent =
					( v1495->EventsSentH[i]<<16 )| v1495->EventsSentL[i];
				v1495Channels[i].LengthDataFIFO--;
				v1495Channels[i].DeltaFrames++;
				v1495Channels[i].TotalFrames++;
				v1495Channels[i].LastSize = v1495->EventSize[i] & EVENT_SIZE_MASK;

			
		   for(j=0; j<v1495Channels[i].LastSize; j++) {
			v1495Channels[i].LastCapture[j] = v1495->EventData[i][0];
			if(j==2) {
				if((v1495Channels[i].LastCapture[j]&0xF000) == 0xE000)	
					v1495Channels[i].LastCapture[j] = (v1495Channels[i].LastCapture[j] & 0x0FFF) | ((USHORT)i<<12);
				else {
					printf("v1495ReadEvent: Error: header for word 3 from data packet != 0xE\n");
					return(ERROR);
				}
			}
		   }
	
		   v1495Channels[i].DeltaBytes += 2 * v1495Channels[i].LastSize;
		   v1495Channels[i].TotalBytes += 2 * v1495Channels[i].LastSize;
				
		   //printf("v1495ReadEvent: Data entered into v1495Channel[%i]\n",i);
		   
/*		   for(j=3; j<11; j=j+2) {
			ChannelsNum[0] = (((j>>1)-1)<<5)+1;
			ChannelsNum[1] =  (j>>1)<<5;
			printf("Channels %d -> %d: ",ChannelsNum[0], ChannelsNum[1]);
			for(k=0;k<2;k++) {
				v1495HextoBin(v1495Channels[i].LastCapture[j+k],HextoBin);
				for(m=0;m<4;m++)
					printf("%04X ",HextoBin[m]);		
			}

			printf("\n");
		   }
*/
		}
	   }

	}
	else
	{
		printf("v1495ReadEvent: dataFIFO is empty\n");
		nWords = 0;
	}	
	return(nWords);
}

int
v1495FillData(UINT32 * data)
{
	int i, nWords = 0;	

//	printf("Data addr: 0x%08X\n", data);

	if(data == NULL) {
    		printf("v1495FillData: ERROR : data not initialized \n");
    		return(-1);
  	}

	nWords = v1495ReadEvent();

	//printf("v1495ReadEvent: filling %d words into data[0x%Xkk]\n",nWords,data);	
	for(i=0; i< nWords; i++)
	{
	   data[i] = *((UINT32 *)(v1495Channels) + i);		
	}
	
//	if(nWords)
//		printf("v1495ReadEvent: %d words copied into data[]\n",nWords);	
	
	return nWords;
}



void v1495StatusPrint(void)//UINT32 * buf)
{
	unsigned int i, j, sent, ChipID[NUM_VFATS], EventID[NUM_VFATS];
	//UINT32 Addr = 0x80110000;
	//volatile V1495ReadoutCtrlRegs * pV1495ReadoutCtrl = (V1495ReadoutCtrlRegs *) Addr;

	//v1495Channels = (V1495ReadoutStatus *)buf;

	for(i=0; i<NUM_VFATS; i++)
	{
		
		printf("V1495[%d]: #B[%u] #F[%u/%u] B/s[%u] F/s[%u]\n", // LstEvtCnt[%u] LstWrdCnt[%u]\n",
			i, v1495Channels[i].TotalBytes, v1495Channels[i].TotalFrames, v1495Channels[i].Sent, 				v1495Channels[i].DeltaBytes, v1495Channels[i].DeltaFrames);//, 					//v1495Channels[i].LastEventCount, v1495Channels[i].LastWordCount);
		
		
		v1495Channels[i].DeltaBytes = 0;
		v1495Channels[i].DeltaFrames = 0;

		printf("  LastCap[%u]: ", v1495Channels[i].LastSize);
		for(j = 0; j < v1495Channels[i].LastSize; j++)
			printf("%04X ", v1495Channels[i].LastCapture[j]);
		printf("\n");
		if(v1495Channels[i].LastSize)
		{
			EventID[i] = (v1495Channels[i].LastCapture[1] & 0x0FF0)>>4;
			ChipID[i] = v1495Channels[i].LastCapture[2] & 0x0FFF;
			printf("Event Count: %d ; Chip ID : 0x%X\n", EventID[i], ChipID[i]);
		}
	}
}