//  trigger.c 
//      This is the basic program for TS/TI/TD operations with production firmware (A24 register map).  
//      This program is to be improved and expanded gradually.
//      Copied from ts.c  -- May 3, 2012


#include <stdioLib.h>
#include <usrLib.h>
#include <cacheLib.h>
#include <iv.h>
#include <math.h>

#define TS_REG_ADDR  0x300000	  /*  default base address of slot#6   (A24) */
#define TS_DATA_ADDR  0x08080000 /*  base address of data space  (A32) for MVME5100 */

void cpuDelay(unsigned long delays);
void IntReset(unsigned int islot);
void EmergencyS(unsigned int islot, unsigned int jtagType, unsigned int numBits, unsigned long jtagData);
void Emergency(unsigned int islot, unsigned int jtagType, unsigned int numBits, unsigned long *jtagData);
void TrgLinkReset(unsigned int islot);
void TrgSrcEnable(unsigned int islot, unsigned int TrgSrc);
void TrgDAQSet(unsigned int islot, unsigned int BlockSize, unsigned int CrateID);
void EMFPGAreload(unsigned int islot);
void TSSet(unsigned int islot, unsigned int BlockSize, unsigned int CrateID);
unsigned long TIDSSerialNumber(unsigned int islot);
void BRAMload(unsigned long A24Add, unsigned int OutWidth);

extern usrVmeDmaConfig();	/* for Tempe DMA */
extern sysVmeDmaInit();		/* for Universe DMA */
extern sysVmeDmaSet();
extern sysVmeDmaCopy();		/* for DMA */
extern sysVmeDmaSend();
extern sysVmeDmaDone();

// custom test setup
void customtest(unsigned int tsslot, unsigned int tislot, unsigned int number)
{
  unsigned int i, j;
  unsigned long *laddr, baseadd, basetiadd;

  baseadd = (tsslot<<19)&0xf80000;
  basetiadd = (tislot<<19)&0xf80000;
  for (i=1; i<number; i++)
    {TSsetup(tsslot);
    sleep(8);
    TIsetup(tislot);
    sleep(5);
    sysBusToLocalAdrs(0x39,basetiadd+0x50, &laddr);
    *laddr = 0xc000;
    cpuDelay(10000);
    TDSstart(tsslot);
    sleep(1);
    TIDSstart(tsslot);
    sleep(1);
    sysBusToLocalAdrs(0x39,baseadd+0x20, &laddr);
    *laddr = 0x104;
    sysBusToLocalAdrs(0x39,baseadd+0x28, &laddr);
    *laddr = 0;
    TRGTableLoad(tsslot);
    FPTableLoad(tsslot);
    cpuDelay(1000000);
    sysBusToLocalAdrs(0x39,baseadd+0x74, &laddr);
    *laddr = 0xffffffff;
    sysBusToLocalAdrs(0x39,baseadd+0x48, &laddr);
    *laddr = 0xf;
    sleep(3);

    sysBusToLocalAdrs(0x39,basetiadd+0x50, &laddr);
    printf(" \n \n TI delay setting: %08x \n", *laddr);

    sysBusToLocalAdrs(0x39,basetiadd+0xB8, &laddr);
    printf(" TI trigger buffer: %08x \n \n", *laddr);


    for (j=1;j<5; j++)
      { sysBusToLocalAdrs(0x39,baseadd+0x78, &laddr);
        *laddr = 0x77;
	cpuDelay(10000);
        *laddr = 0xdd;
	sleep(1);
        *laddr = 0x55;
	printf(" loop i: %02x,  j of %01x \n",i, j);
        sleep(3); }
    }
}

// SubTS setup
void RepeatTrg(unsigned int number)
{
  unsigned int i;
  for (i=1; i<number; i++)
    {TDSstart(21);
    cpuDelay(1000000);
    printf(" \n Loop number: %d", i);
    TIDSstart(21);
    cpuDelay(40000000);}
}

void ReadRepeat(unsigned int tmslot)
{
  unsigned long *laddr, BaseAdd, DataWord;
  unsigned int i, ByteRead;
  BaseAdd = (tmslot<<19)&0xf80000;

  for (i=1; i<100000; i++)
    { cpuDelay(10000);
      sysBusToLocalAdrs(0x39,BaseAdd+0xd0, &laddr);
      DataWord = *laddr;
      if ( (DataWord & 0xff0000) > 0 )
      { ByteRead=tidsBERead(tmslot) ;
        sysBusToLocalAdrs(0x39,BaseAdd+0x100, &laddr);
        *laddr = 0x80;
        printf(" ByteRead %08x at %08x \n",ByteRead,i);
        cpuDelay(1000);
      }
    }
}
void SubTSSetup(unsigned int islot)
{
  unsigned long *laddr;
  unsigned long BaseAdd;

  BaseAdd = ((islot<<19)&0xf80000);

  TIDSsetup(islot, 2);
  sysBusToLocalAdrs(0x39,( BaseAdd+0x14), &laddr);
  *laddr = 1;
  SubTSTableLoad(islot,1);
  SubTSTableLoad(islot,2);
  SubTSTableLoad(islot,3);
  SubTSTableLoad(islot,4);
  cpuDelay(1000);
  sysBusToLocalAdrs(0x39, BaseAdd+0x70, &laddr);
  *laddr = 0x00e00000;
  cpuDelay(1000);
  sysBusToLocalAdrs(0x39, BaseAdd+0x148, &laddr);
  *laddr = 0x1d;
  cpuDelay(1000);
  sysBusToLocalAdrs(0x39, BaseAdd+0x348, &laddr);
  *laddr = 0x1d;
  cpuDelay(1000);
  sysBusToLocalAdrs(0x39, BaseAdd+0x548, &laddr);
  *laddr = 0x1d;
  cpuDelay(1000);
  sysBusToLocalAdrs(0x39, BaseAdd+0x748, &laddr);
  *laddr = 0x1d;
  cpuDelay(1000);
  sysBusToLocalAdrs(0x39, BaseAdd+0x158, &laddr);
  *laddr = 0x77030000;
  cpuDelay(1000);
  sysBusToLocalAdrs(0x39, BaseAdd+0x358, &laddr);
  *laddr = 0x77030000;
  cpuDelay(1000);
  sysBusToLocalAdrs(0x39, BaseAdd+0x558, &laddr);
  *laddr = 0x77030000;
  cpuDelay(1000);
  sysBusToLocalAdrs(0x39, BaseAdd+0x758, &laddr);
  *laddr = 0x77030000;
}

//single BRAM unit loading	 
void BRAMload(unsigned long A24Add, unsigned int OutWidth)
{
  unsigned long *laddr, FirstWord;
  unsigned int i;

  // Reset the write address first
  sysBusToLocalAdrs(0x39, ((A24Add&0xf80000)+0x100), &laddr);
  *laddr = 0x1000;
  cpuDelay(0x100000);  //1ms delay

  printf(" A24Add inside BRAM load is: %08x \n", A24Add);

  sysBusToLocalAdrs(0x39,A24Add,&laddr);
  // load the first word, so that the trigger_out is low when all the table inputs are low
  if (OutWidth == 1) FirstWord = 0xfffffffe;
  else if (OutWidth == 2) FirstWord = 0xfffffffc;
  else if (OutWidth == 4) FirstWord = 0xfffffff0;
  else if (OutWidth == 8) FirstWord = 0xffffff00;
  else FirstWord = 0xffff0000;
  *laddr = FirstWord;
  printf(" FirstWord Loaded: %08x\n", FirstWord);

  // load the rest with trigger_out = 1
  for (i=1; i<1024;i++)
    {
      *laddr = 0xffffffff;
      cpuDelay(100);   // ~us delay
    }
}

void GTPTableLoad(unsigned int islot)
{
  unsigned long A24Base, A24Add;
  unsigned int i;

  A24Base = (islot<<19)&0xf80000;

  printf(" Base address is %08x \n", A24Base);

  // load the first 15x8 table
  for (i=0; i<8; i++)
  {
    A24Add = A24Base + 0x1100 + i*4;

    printf(" A24 address is %08x \n", A24Add);

    BRAMload(A24Add,1);
  }

  // load the second 15x8 table
  for (i=0; i<8; i++)
  {
    A24Add = A24Base + 0x1140 + i*4;

    printf(" A24 address is %08x \n", A24Add);

    BRAMload(A24Add,1);
  }

  // load the first 15x11 table
  for (i=0; i<11; i++)
  {
    A24Add = A24Base + 0x1180 + i*4;

    printf(" A24 address is %08x \n", A24Add);

    BRAMload(A24Add,1);
  }

  // load the second 15x11 table
  for (i=0; i<11; i++)
  {
    A24Add = A24Base + 0x11C0 + i*4;

    printf(" A24 address is %08x \n", A24Add);

    BRAMload(A24Add,1);
  }
  printf(" GTP block ram loaded, last address is : %08x \n", A24Add);
}

void EXTTableLoad(unsigned int islot)
{
  unsigned long A24Base, A24Add;
  unsigned int i;

  A24Base = (islot<<19)&0xf80000;

  printf(" Base address is %08x \n", A24Base);

  // load the first 15x8 table
  for (i=0; i<8; i++)
  {
    A24Add = A24Base + 0x1200 + i*4;

    printf(" A24 address is %08x \n", A24Add);

    BRAMload(A24Add,1);
  }

  // load the second 15x8 table
  for (i=0; i<8; i++)
  {
    A24Add = A24Base + 0x1240 + i*4;

    printf(" A24 address is %08x \n", A24Add);

    BRAMload(A24Add,1);
  }

  // load the first 15x11 table
  for (i=0; i<11; i++)
  {
    A24Add = A24Base + 0x1280 + i*4;

    printf(" A24 address is %08x \n", A24Add);

    BRAMload(A24Add,1);
  }

  // load the second 15x11 table
  for (i=0; i<11; i++)
  {
    A24Add = A24Base + 0x12C0 + i*4;

    printf(" A24 address is %08x \n", A24Add);

    BRAMload(A24Add,1);
  }
  printf(" EXT block ram loaded, last address is : %08x \n", A24Add);
}

void FPTableLoad(unsigned int islot)
{
  unsigned long A24Base, A24Add;
  unsigned int i;

  A24Base = (islot<<19)&0xf80000;

  printf(" Base address is %08x \n", A24Base);

  // load the 15x8 table
  for (i=0; i<8; i++)
  {
    A24Add = A24Base + 0x1300 + i*4;
    printf(" A24 Address is %08x \n", A24Add);
    BRAMload(A24Add,1);
  }

  printf(" FP block ram loaded, last address is : %08x \n", A24Add);
}

void TRGTableLoad(unsigned int islot)
{
  unsigned long A24Base, A24Add;
  unsigned int i;

  A24Base = (islot<<19)&0xf80000;

  // load the first 15x11 table
  //  for (i=0; i<11; i++)
  for (i=3; i<5; i++)
  {
    A24Add = A24Base + 0x1000 + i*4;
    printf(" A24 address to load %08x \n", A24Add);
    BRAMload(A24Add,1);
  }
    A24Add = A24Base + 0x1000 + 40;
    printf(" A24 address to load %08x \n", A24Add);
    BRAMload(A24Add,1);

  // load the second 15x11 table
  //  for (i=0; i<11; i++)
  for (i=3; i<5; i++)
  {
    A24Add = A24Base + 0x1040 + i*4;
    printf(" A24 Address to load %08x \n", A24Add);
    BRAMload(A24Add,1);
  }
  printf(" Final Triggerr block ram loaded, last address is : %08x \n", A24Add);
}

void SubTSTableLoad(unsigned int islot, unsigned int iTS)
{
  unsigned long A24Base, A24Add;
  unsigned int i;

  A24Base = ( ((islot<<19)&0xf80000) + 0x4c + (((iTS*2-1)<<8)&0x700) );
  A24Add = A24Base;
  printf(" Base address is %08x \n", A24Base);

  // load the 13x8 table
  BRAMload(A24Base,4);

  printf(" SubTS #%01x block ram loaded, The VME A24 address is : %08x \n", iTS, A24Add);
}



void tsIRQEn(unsigned int islot,unsigned int Ilevel, unsigned int Iid)
{
  unsigned long *laddr;
  unsigned long Dataword;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  // A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd+8,&laddr);
  *laddr = (0x10000 + ((Ilevel<<8)&0x700)+(Iid&0xff));
  intDisconnect(Iid&0xff);
  intConnect(Iid&0xff, IntReset,islot);
  sysIntEnable(Ilevel&0xf);
  printf (" \n IRQ is setup \n");
}

void IntReset(unsigned int islot)
{ unsigned long *laddr;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);
  *laddr = 0x80;
  //  printf(" \n  DAQ acknowledged \n");
}

unsigned long FPGAusercode(unsigned int islot)
{
  unsigned long *laddr;
  unsigned long Dataword;
  unsigned long RegAdd;

  RegAdd = ((islot << 19) & 0xf80000);

  // A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);		/* reset */
  *laddr = 0x04;
  sysBusToLocalAdrs(0x39,RegAdd+0x2003c,&laddr);       
  *laddr = 0x0;                                         // Reset_idle
  sysBusToLocalAdrs(0x39,RegAdd+0x2092c,&laddr);
  *laddr = 0x3c8;                                       // load the UserCode Enable
  sysBusToLocalAdrs(0x39,RegAdd+0x21f1c,&laddr);
  *laddr = 0x00;    // shift in 32-bit of data
  Dataword = *laddr;
  printf (" \n FPGA UserCode is %x in slot# %d \n", Dataword,islot);
  return Dataword;
}
unsigned long FPGAchipcode(unsigned int islot)
{
  unsigned long *laddr;
  unsigned long Dataword;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  // A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);		/* reset */
  *laddr = 0x04;
  sysBusToLocalAdrs(0x39,RegAdd+0x2003c,&laddr);       
  *laddr = 0x0;                                         // Reset_idle
  sysBusToLocalAdrs(0x39,RegAdd+0x2092c,&laddr);
  *laddr = 0x3c9;                                       // load the ChipCode Enable
  sysBusToLocalAdrs(0x39,RegAdd+0x21f1c,&laddr);
  *laddr = 0x00;                                        // shift in 32-bit of data
  Dataword = *laddr;
  printf (" \n FPGA ChipCode is %x in slot# %d \n", Dataword, islot);
  return Dataword;
}

unsigned long PROMusercode(unsigned int islot)
{
  unsigned long *laddr;
  unsigned long Dataword;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  // A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);		/* reset */
  *laddr = 0x04;
    sysBusToLocalAdrs(0x39,RegAdd+0x1003c,&laddr);       
   *laddr = 0x0;                                         // Reset_idle
  sysBusToLocalAdrs(0x39,RegAdd+0x10f2c,&laddr);
  *laddr = 0x00FD;                                       // load the UserCode Enable
  sysBusToLocalAdrs(0x39,RegAdd+0x11f1c,&laddr);
  *laddr = 0x00;                                        // shift in 32-bit of data
  Dataword = *laddr;
  printf (" \n PROM UserCode is %x in slot# %d \n", Dataword, islot);
  return Dataword;
}

unsigned long TIDSSerialNumber(unsigned int islot)
{
  unsigned long *laddr;
  unsigned long Dataword;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  // A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);		/* reset */
  *laddr = 0x04;
    sysBusToLocalAdrs(0x39,RegAdd+0x1003c,&laddr);       
   *laddr = 0x0;                                         // Reset_idle
  sysBusToLocalAdrs(0x39,RegAdd+0x10f2c,&laddr);
  *laddr = 0x00FD;                                       // load the UserCode Enable
  sysBusToLocalAdrs(0x39,RegAdd+0x11f1c,&laddr);
  *laddr = 0x00;                                        // shift in 32-bit of data
  Dataword = *laddr;
  printf (" \n The board serial number is %x in slot# %d \n", Dataword, islot);
  return Dataword;
}

// Global trigger distribution crate setup
void TScrate(void)
{
  TSsetup(21);
  cpuDelay(1000000);
  TDsetup(9);
  cpuDelay(1000000);
  TDsetup(14);
  cpuDelay(1000000);
  TDsetup(16);
  cpuDelay(1000000);
  TDsetup(18);
  cpuDelay(1000000);
  TDsetup(7);
  cpuDelay(1000000);
}

// T-frame TI crate (with DAVW4) setup
void TIcrate4(void)
{
  TIsetup(3);
  cpuDelay(1000000);
  TIsetup(4);
  cpuDelay(1000000);
  TIsetup(5);
  cpuDelay(1000000);
  TIsetup(6);
  cpuDelay(1000000);
}

// VXS crate with DAVW5 setup
void TIcrate5(void)
{
  TIsetup(4);
  cpuDelay(1000000);
  TIsetup(5);
  cpuDelay(1000000);
  TIsetup(6);
  cpuDelay(1000000);
  TIsetup(7);
  cpuDelay(1000000);
  TIsetup(20);
  cpuDelay(1000000);
}

//TS setup, There is no TI in the crate
void TSsetup(unsigned int islotTS)
{
  unsigned long *laddr;
  unsigned long Dataword;
  unsigned long RegAddTS;

  RegAddTS = ((islotTS<<19)&0xf80000);

  // FPGA reload, needs ~1 second
  EMFPGAreload(islotTS);
  cpuDelay(200000000);

  // Enable TS optic transceiver
  sysBusToLocalAdrs(0x39,RegAddTS+0x4,&laddr);	
  *laddr = 0xf;
  cpuDelay(300000);

  //Set TS block size
  sysBusToLocalAdrs(0x39,RegAddTS+0x14,&laddr);
  *laddr = 0x0a; 
  cpuDelay(0x30000);
  sysBusToLocalAdrs(0x39,RegAddTS+0x18,&laddr);  // data format
  *laddr = 0x60000003;
  cpuDelay(100000);

  //Set TS sync pulse width
  sysBusToLocalAdrs(0x39,RegAddTS+0x80,&laddr);
  *laddr = 0x10; 
  cpuDelay(0x30000);

  //Set TS loopback sync pulse delay
  sysBusToLocalAdrs(0x39,RegAddTS+0x50,&laddr);
  *laddr = 0x0a0b0c0d; 
  cpuDelay(0x30000);

  //Set TS ID
  sysBusToLocalAdrs(0x39,RegAddTS,&laddr);
  *laddr = 0x55; 
  cpuDelay(0x30000);

  // Set TS trigger pulse width
  sysBusToLocalAdrs(0x39,RegAddTS+0x0c,&laddr);
  *laddr = 0x0f000f00;
  cpuDelay(30000);

  //Set TS trigger source (VME, random, loopback)
  sysBusToLocalAdrs(0x39,RegAddTS+0x20,&laddr);
  *laddr = 0x90; 
  cpuDelay(30000);

  //Set TS SYNC source (loopback)
  sysBusToLocalAdrs(0x39,RegAddTS+0x24,&laddr);
  *laddr = 0x10; 
  cpuDelay(30000);

  //Set TS BUSY source (loopback)
  sysBusToLocalAdrs(0x39,RegAddTS+0x28,&laddr);
  *laddr = 2; //enable SW#B busy only
  cpuDelay(30000);

  // TS IODELAY reset
  sysBusToLocalAdrs(0x39,RegAddTS+0x100,&laddr);
  *laddr = 0x4000; 
  cpuDelay(3000000);

  // TS trigger stop
  sysBusToLocalAdrs(0x39,RegAddTS+0x78,&laddr);
  *laddr = 0x77; 
  cpuDelay(300000);

  //Set TS sync delay (delay before SYNC being serialized)
  sysBusToLocalAdrs(0x39,RegAddTS+0x7C,&laddr);
  *laddr = 0x3f; 
  cpuDelay(0x300000);

  //one more TS trigger stop
  sysBusToLocalAdrs(0x39,RegAddTS+0x78,&laddr);
  *laddr = 0x77; 
  cpuDelay(300000);

  //check the TS states
  sysBusToLocalAdrs(0x39,RegAddTS,&laddr);
  printf(" TS state register is %08x at slot %d\n", *laddr, islotTS);

  printf (" \n TS setup ready \n");
}


// TD setup
void TDsetup(unsigned int islotTD)
{
  unsigned long *laddr;
  unsigned long Dataword;
  unsigned long RegAddTD;

  RegAddTD = ((islotTD<<19)&0xf80000);

  // FPGA reload, need ~30ms
  EMFPGAreload(islotTD);  
  cpuDelay(10000000);

  // Enable TD optic transceivers
  sysBusToLocalAdrs(0x39,RegAddTD+0x4,&laddr);	
  *laddr = 0xFF;
  cpuDelay(300000);

  // Trigger source enable set to 'VME', for the live/busy timer to work
  sysBusToLocalAdrs(0x39, RegAddTD+0x20,&laddr);
  *laddr = 0x10;

  printf("\n\n TD set to source 0x10 in TDsetup\n\n");

  cpuDelay(30000);

  // Enable TD Sync source input from P0
  sysBusToLocalAdrs(0x39,RegAddTD+0x24,&laddr);	
  *laddr = 0x11;  //loop back is required, or else the TD can not get the SYNC command
  cpuDelay(300000);

  // TD IOdelay reset
  sysBusToLocalAdrs(0x39,RegAddTD+0x100,&laddr);	
  *laddr = 0x4000;
  cpuDelay(3000000);

  // TD auto align the P0 sync input
  sysBusToLocalAdrs(0x39,RegAddTD+0x100,&laddr);	
  *laddr = 0x800;
  cpuDelay(3000000);

  //to add the backpressure setup later
  // Set the threshold for number of data blocks.
  sysBusToLocalAdrs(0x39,RegAddTD+0x14,&laddr);	
  *laddr = 0xa; // set the block size
  cpuDelay(300000);
  sysBusToLocalAdrs(0x39,RegAddTD+0x34,&laddr);	
  *laddr = 2*islotTD;  // set the blockNumber threshold
  cpuDelay(300000);

  // Set the trigger source to P2Busy, which is BusyEn(6), enable HFBR according to the connection
  sysBusToLocalAdrs(0x39,RegAddTD+0x28,&laddr);	
  if (islotTD == 7) 
    *laddr = 0x40 + 0x100;
  else if (islotTD == 9) 
    *laddr = 0x40 + 0x200 + 0x4000;
  else if (islotTD == 14) 
    *laddr = 0x40 + 0x400 + 0x2000; // +0x800 + 0x1000 +0x8000;
  else if (islotTD == 16)
    *laddr = 0x40 + 0x400;
  else if (islotTD == 18)
    *laddr = 0x40 + 0x800 + 0x1000 + 0x8000;
  else
    *laddr = 0x40;

  cpuDelay(300000);

}

// TI setup 
void TIsetup(unsigned int islotTI)
{
  unsigned long *laddr;
  unsigned long Dataword;
  unsigned long RegAddTI;

  RegAddTI = ((islotTI<<19)&0xf80000);

  // FPGA reload, needs ~30 ms
  EMFPGAreload(islotTI);
  cpuDelay(10000000);

  // Enable TI optic transceiver#1
  sysBusToLocalAdrs(0x39,RegAddTI+0x4,&laddr);	
  *laddr = 0x1;
  cpuDelay(300000);

  // TI readout setting
  // Enable TI VME setting
  sysBusToLocalAdrs(0x39,RegAddTI+0x1C,&laddr);	
  *laddr = 0x11;
  cpuDelay(300000);
  // Set TI IRQ, but not enabled yet (set bit 16 to 1 to enable it)
  sysBusToLocalAdrs(0x39,RegAddTI+0x8,&laddr);	
  *laddr = 0x5c0 + (islotTI&0x1f);
  cpuDelay(300000);
  // Enable TI A32 address
  sysBusToLocalAdrs(0x39,RegAddTI+0x10,&laddr);	
  *laddr = (0x8003fe0+ (0xf80000 & (islotTI<<23)));
  cpuDelay(300000);
 

  // TI clock selection, to use HFBR#1
   sysBusToLocalAdrs(0x39,RegAddTI+0x2c,&laddr);    
   *laddr = 0x2;
   cpuDelay(300000);

   // TI clock DCM reset
  sysBusToLocalAdrs(0x39,RegAddTI+0x100,&laddr);
  *laddr = 0x0100;
  cpuDelay(300000);
  *laddr = 0x0200;
  cpuDelay(300000);

  // Fiber length measurement and compensation
  FiberMeas(islotTI);
  cpuDelay(1000000);

  // Enable TI trigger source and sync source 
  sysBusToLocalAdrs(0x39,RegAddTI+0x20,&laddr);  //trigger source
  *laddr = 0x92;  //enable the HFRB#1 input and VME input
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0xC,&laddr);  //trigger pulse width and delay
  *laddr = 0x0f000f00;
  cpuDelay(100000);
  //  sysBusToLocalAdrs(0x39,RegAddTI+0x50,&laddr); // sync delay
  //  *laddr = 0x0f0e0d0c;
  //  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0x80,&laddr); // sync pulse width
  *laddr = 0x24;
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0x24,&laddr); // sync source
  *laddr = 0x2;
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0x14,&laddr); // block size
  *laddr = 0xa;
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI,&laddr);  //crate id
  *laddr = 0x66;
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0x18,&laddr);  // data format
  *laddr = 0x60000003;
  cpuDelay(100000);

  // TI IODELAY reset
  sysBusToLocalAdrs(0x39,RegAddTI+0x100,&laddr);
  *laddr = 0x4000; 
  cpuDelay(3000000);

  // TI Sync auto alignment
  sysBusToLocalAdrs(0x39,RegAddTI+0x100,&laddr);
  *laddr = 0x800; 
  cpuDelay(3000000);

  // TI auto fiber delay measurement
  *laddr = 0x8000; 
  cpuDelay(3000000);

  // TI auto alignement fiber delay
  *laddr = 0x2000; 
  cpuDelay(3000000);

  // TI sync delay (no use for TIslave) and sync pulse width
  sysBusToLocalAdrs(0x39,RegAddTI+0x80,&laddr);
  *laddr = 0x3f; 
  cpuDelay(300000);

  //Set TI MGT synchronization
  sysBusToLocalAdrs(0x39,RegAddTI+0x100,&laddr);
  *laddr = 0x400; 
  cpuDelay(3000000);

  //Set TI to running mode, so that the clock monitoring start to work
  sysBusToLocalAdrs(0x39,RegAddTI+0x9c,&laddr);
  *laddr = 0x71; 
  cpuDelay(300000);

  //check the TI states
  sysBusToLocalAdrs(0x39,RegAddTI,&laddr);
  printf(" TI state register is %08x at slot %d\n", *laddr, islotTI);

  printf (" \n TI setup ready \n");
}

// TI setup as a subsystem TI
void TIsubsetup(unsigned int islotTI)
{
  unsigned long *laddr;
  unsigned long Dataword;
  unsigned long RegAddTI;

  RegAddTI = ((islotTI<<19)&0xf80000);

  // FPGA reload, needs ~30 ms
  EMFPGAreload(islotTI);
  cpuDelay(10000000);

  // Enable TI optic transceiver#5
  sysBusToLocalAdrs(0x39,RegAddTI+0x4,&laddr);	
  *laddr = 0x10;
  cpuDelay(300000);

  // TI readout setting
  // Enable TI VME setting
  sysBusToLocalAdrs(0x39,RegAddTI+0x1C,&laddr);	
  *laddr = 0x11;
  cpuDelay(300000);
  // Set TI IRQ, but not enabled yet (set bit 16 to 1 to enable it)
  sysBusToLocalAdrs(0x39,RegAddTI+0x8,&laddr);	
  *laddr = 0x5c0 + (islotTI&0x1f);
  cpuDelay(300000);
  // Enable TI A32 address
  sysBusToLocalAdrs(0x39,RegAddTI+0x10,&laddr);	
  *laddr = (0x8003fe0+ (0xf80000 & (islotTI<<23)));
  cpuDelay(300000);
 

  // TI clock selection, to use HFBR#5
   sysBusToLocalAdrs(0x39,RegAddTI+0x2c,&laddr);    
   *laddr = 0x1;
   cpuDelay(300000);

   // TI clock DCM reset
  sysBusToLocalAdrs(0x39,RegAddTI+0x100,&laddr);
  *laddr = 0x0100;
  cpuDelay(300000);
  *laddr = 0x0200;
  cpuDelay(300000);

  // Fiber length measurement and compensation
  FiberMeas(islotTI);
  cpuDelay(1000000);

  // Enable TI trigger source and sync source 
  sysBusToLocalAdrs(0x39,RegAddTI+0x20,&laddr);  //trigger source
  *laddr = 0x400;  //enable the HFRB#5 input and VME input
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0xC,&laddr);  //trigger pulse width and delay
  *laddr = 0x0f000f00;
  cpuDelay(100000);
  //  sysBusToLocalAdrs(0x39,RegAddTI+0x50,&laddr); // sync delay
  //  *laddr = 0x0f0e0d0c;
  //  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0x80,&laddr); // sync pulse width
  *laddr = 0x24;
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0x24,&laddr); // sync source
  *laddr = 0x4;
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0x14,&laddr); // block size
  *laddr = 0xa;
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI,&laddr);  //crate id
  *laddr = 0x66;
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0x18,&laddr);  // data format
  *laddr = 0x60000003;
  cpuDelay(100000);

  // TI IODELAY reset
  sysBusToLocalAdrs(0x39,RegAddTI+0x100,&laddr);
  *laddr = 0x4000; 
  cpuDelay(3000000);

  // TI Sync auto alignment
  sysBusToLocalAdrs(0x39,RegAddTI+0x100,&laddr);
  *laddr = 0x800; 
  cpuDelay(3000000);

  // TI auto fiber delay measurement
  *laddr = 0x8000; 
  cpuDelay(3000000);

  // TI auto alignement fiber delay
  *laddr = 0x2000; 
  cpuDelay(3000000);

  // TI sync delay (no use for TIslave) and sync pulse width
  sysBusToLocalAdrs(0x39,RegAddTI+0x80,&laddr);
  *laddr = 0x3f; 
  cpuDelay(300000);

  //Set TI MGT synchronization
  sysBusToLocalAdrs(0x39,RegAddTI+0x100,&laddr);
  *laddr = 0x400; 
  cpuDelay(3000000);

  //Set TI to running mode, so that the clock monitoring start to work
  sysBusToLocalAdrs(0x39,RegAddTI+0x9c,&laddr);
  *laddr = 0x71; 
  cpuDelay(300000);

  //check the TI states
  sysBusToLocalAdrs(0x39,RegAddTI,&laddr);
  printf(" TI state register is %08x at slot %d\n", *laddr, islotTI);

  printf (" \n TI setup ready \n");
}


// Trigger distribution system start up, the TS slot number is the only input
void TIDSstart(unsigned int islotTS)
{
  unsigned long *laddr;
  unsigned long RegAddTS;

  RegAddTS = ((islotTS<<19)&0xf80000);

  //Stop trigger, and set the MGT to idle state
  sysBusToLocalAdrs(0x39,RegAddTS+0x78,&laddr);
  *laddr = 0x77; 
  cpuDelay(3000); 

  *laddr = 0x77; 
  cpuDelay(3000); 

  // MGT re-sync only
  sysBusToLocalAdrs(0x39,RegAddTS+0x100,&laddr);
  //  *laddr = 0x400;
  cpuDelay(1000000);

  //Set TS sync reset (generic)
  sysBusToLocalAdrs(0x39,RegAddTS+0x78,&laddr);
  *laddr = 0xdd; 
  cpuDelay(300000);

  //Stop trigger, and set the MGT to idle state
  sysBusToLocalAdrs(0x39,RegAddTS+0x78,&laddr);
  *laddr = 0x77; 
  cpuDelay(300000); 

  //Trigger link start
  *laddr =0x55;
  cpuDelay(0x100000);

  // One more reset
  *laddr = 0xdd;
  cpuDelay(0x100000);

  // start triggering 0x100 events
  sysBusToLocalAdrs(0x39,RegAddTS+0x8c,&laddr);	// VME trigger
  *laddr = 0xa1950020;  // 0x10 triggers
  //  sysBusToLocalAdrs(0x39,RegAddTS+0x20,&laddr);
  //  *laddr = 0x100;

}

// setup the TS/TD crate only:
void TDSstart(unsigned int islotTS)
{
  unsigned long *laddr;
  unsigned long RegAddTS;

  RegAddTS = ((islotTS<<19)&0xf80000);

  //Stop trigger, and set the MGT to idle state
  sysBusToLocalAdrs(0x39,RegAddTS+0x78,&laddr);
  *laddr = 0x77; 
  cpuDelay(300000);
  // one more stop command
  sysBusToLocalAdrs(0x39,RegAddTS+0x78,&laddr);
  *laddr = 0x77; 
  cpuDelay(300000);

  // MGT reset
  sysBusToLocalAdrs(0x39,RegAddTS+0x78,&laddr);	
  *laddr = 0x33; // AD9510 slow clock sync
  cpuDelay(100);
  
  *laddr = 0x22;  // MGT 'CLKSYN'
  cpuDelay(10000000);

  //set up the sync pulse width and encoding dely
  sysBusToLocalAdrs(0x39,RegAddTS+0x80,&laddr);
  *laddr = 0x2f;  //Sync pulse width (0x2f) after being decoded
  cpuDelay(0x100);
   sysBusToLocalAdrs(0x39,RegAddTS+0x7c,&laddr);
  *laddr = 0x54;  // Sync delay (0x54) before being serialized
  cpuDelay(0x100);

  //Set TS sync reset (generic)
  sysBusToLocalAdrs(0x39,RegAddTS+0x78,&laddr);
  *laddr = 0xdd; 
  cpuDelay(300000);
}

// When the TS and TI are in the same crate, the TIA or TIB optic transceiver connects from TS to TI.
void TIDSsetup(unsigned int islotTS, unsigned int islotTI)
{
  unsigned long *laddr;
  unsigned long Dataword;
  unsigned long RegAddTS, RegAddTI;

  RegAddTS = ((islotTS<<19)&0xf80000);
  RegAddTI = ((islotTI<<19)&0xf80000);

  // Enable TI optic transceiver#1
  sysBusToLocalAdrs(0x39,RegAddTI+0x4,&laddr);	
  *laddr = 0x1;
  cpuDelay(300000);

  // Enable TS optic transceiver
  sysBusToLocalAdrs(0x39,RegAddTS+0x4,&laddr);	
  *laddr = 0xf;
  cpuDelay(300000);

  // TI readout setting
  // Enable TI VME setting
  sysBusToLocalAdrs(0x39,RegAddTI+0x1C,&laddr);	
  *laddr = 0x11;
  cpuDelay(300000);
  // Enable TI IRQ
  sysBusToLocalAdrs(0x39,RegAddTI+0x8,&laddr);	
  *laddr = 0x5c9;
  cpuDelay(300000);
  // Enable TI A32 address
  sysBusToLocalAdrs(0x39,RegAddTI+0x10,&laddr);	
  *laddr = (0x8003fe0+ (0xf80000 & (islotTI<<23)));
  cpuDelay(300000);
 

  // TI clock selection, to use HFBR#1
    sysBusToLocalAdrs(0x39,RegAddTI+0x2c,&laddr);    
   *laddr = 0x2;
   cpuDelay(300000);

   // TI clock DCM reset
  sysBusToLocalAdrs(0x39,RegAddTI+0x100,&laddr);
  *laddr = 0x0100;
  cpuDelay(300000);
  *laddr = 0x0200;
  cpuDelay(300000);

  // Enable TI trigger source and sync source 
  sysBusToLocalAdrs(0x39,RegAddTI+0x20,&laddr);  //trigger source
  *laddr = 0x92;  //enable the HFRB#1 input and VME input
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0xC,&laddr);  //trigger pulse width and delay
  *laddr = 0x0f000f00;
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0x50,&laddr); // sync delay
  *laddr = 0x0f0e0d0c;
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0x80,&laddr); // sync pulse width
  *laddr = 0x24;
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0x24,&laddr); // sync source
  *laddr = 0x2;
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0x14,&laddr); // block size
  *laddr = 0xa;
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI,&laddr);  //crate id
  *laddr = 0x66;
  cpuDelay(100000);
  sysBusToLocalAdrs(0x39,RegAddTI+0x18,&laddr);  // data format
  *laddr = 0x60000003;
  cpuDelay(100000);

  //Set TS block size
  sysBusToLocalAdrs(0x39,RegAddTS+0x14,&laddr);
  *laddr = 0x0a; 
  cpuDelay(0x30000);
  sysBusToLocalAdrs(0x39,RegAddTS+0x18,&laddr);  // data format
  *laddr = 0x60000003;
  cpuDelay(100000);

  //Set TS sync pulse width
  sysBusToLocalAdrs(0x39,RegAddTS+0x80,&laddr);
  *laddr = 0x10; 
  cpuDelay(0x30000);

  //Set TS loopback sync pulse delay
  sysBusToLocalAdrs(0x39,RegAddTS+0x50,&laddr);
  *laddr = 0x0a0b0c0d; 
  cpuDelay(0x30000);

  //Set TS ID
  sysBusToLocalAdrs(0x39,RegAddTS,&laddr);
  *laddr = 0x55; 
  cpuDelay(0x30000);

  //Set TS trigger source (VME, random, loopback)
  sysBusToLocalAdrs(0x39,RegAddTS+0x20,&laddr);
  *laddr = 0x94; 
  cpuDelay(30000);

  //Set TS SYNC source (loopback)
  sysBusToLocalAdrs(0x39,RegAddTS+0x24,&laddr);
  *laddr = 0x10; 
  cpuDelay(30000);

  // TS IODELAY reset
  sysBusToLocalAdrs(0x39,RegAddTS+0x100,&laddr);
  *laddr = 0x4000; 
  cpuDelay(3000000);

  // TI IODELAY reset
  sysBusToLocalAdrs(0x39,RegAddTI+0x100,&laddr);
  *laddr = 0x4000; 
  cpuDelay(3000000);

  // TI Sync auto alignment
  sysBusToLocalAdrs(0x39,RegAddTI+0x100,&laddr);
  *laddr = 0x800; 
  cpuDelay(3000000);

  // TI auto fiber delay measurement
  *laddr = 0x8000; 
  cpuDelay(3000000);

  // TI auto alignement fiber delay
  *laddr = 0x2000; 
  cpuDelay(3000000);

  // TI sync delay (no use for TIslave) and sync pulse width
  sysBusToLocalAdrs(0x39,RegAddTI+0x80,&laddr);
  *laddr = 0x3f; 
  cpuDelay(300000);

  // TS trigger stop
  sysBusToLocalAdrs(0x39,RegAddTS+0x78,&laddr);
  *laddr = 0x77; 
  cpuDelay(300000);

  //Set TI MGT synchronization
  sysBusToLocalAdrs(0x39,RegAddTI+0x100,&laddr);
  *laddr = 0x400; 
  cpuDelay(3000000);

  //Set TS MGT synchronization
  sysBusToLocalAdrs(0x39,RegAddTS+0x100,&laddr);
  *laddr = 0x400; 
  cpuDelay(3000000);

  //Set TS sync delay (delay before SYNC being serialized)
  sysBusToLocalAdrs(0x39,RegAddTS+0x7C,&laddr);
  *laddr = 0x3f; 
  cpuDelay(0x300000);

  //one more TS trigger stop
  sysBusToLocalAdrs(0x39,RegAddTS+0x78,&laddr);
  *laddr = 0x77; 
  cpuDelay(300000);

  //Set TS sync reset (generic)
  sysBusToLocalAdrs(0x39,RegAddTS+0x78,&laddr);
  *laddr = 0xdd; 
  cpuDelay(300000);

  //Set TI to running mode, so that the clock monitoring start to work
  sysBusToLocalAdrs(0x39,RegAddTI+0x9c,&laddr);
  *laddr = 0x71; 
  cpuDelay(300000);
  //check the TI TS states
  sysBusToLocalAdrs(0x39,RegAddTI,&laddr);
  printf(" TI state register is %08x at slot %d\n", *laddr, islotTI);
  sysBusToLocalAdrs(0x39,RegAddTS,&laddr);
  printf(" TS state register is %08x at slot %d\n", *laddr, islotTS);

  printf (" \n TS/TI setup ready \n");
}

// TI master Internal Loop Back setting
void TImasterSet(unsigned int islot, unsigned int BlockSize, unsigned int CrateID)
{
  unsigned long *laddr;
  unsigned long RegAdd, OldValue;

  //FPGA reload
  EMFPGAreload(islot);
  cpuDelay(50000000);

  RegAdd = ((islot<<19)&0xf80000);

  //TI clock setup
  sysBusToLocalAdrs(0x39,RegAdd+0x2C,&laddr);
  *laddr = 0x0000;  //Oscillator input clock is selected
  cpuDelay(0x50000);
  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);
  *laddr = 0x100;  //250MHz DCM reset;
  cpuDelay(0x50000);
  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);
  *laddr = 0x200;  //125 MHz DCm reset
  cpuDelay(0x50000);

  sysBusToLocalAdrs(0x39,RegAdd+0x7C,&laddr);		/* SYNC interface */
  *laddr = 0x54;  // Sync delay (0x54) before being serialized
  cpuDelay(0x100000);
  sysBusToLocalAdrs(0x39,RegAdd+0x80,&laddr);		/* SYNC interface */
  *laddr = 0x2f;  //Sync (reset) width (0x2f) ~2us
  cpuDelay(0x100000);

  // Enable the Fiber transmitters as the default might be OFF
  sysBusToLocalAdrs(0x39,RegAdd+0x04,&laddr);
  *laddr = 0x00FF;  // Enable all the fiber modules, just in case that the TImaster will drive a TIslave
  cpuDelay(5000000);

  // set sync source
  sysBusToLocalAdrs(0x39,RegAdd+0x24,&laddr); 
  *laddr = 0x10; //TImaster internal loop back
  cpuDelay(0x50000);

  //FPGA IOdelay reset
  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);  //sync 
  *laddr = 0x4000;    // reset IODELAY
  cpuDelay(10000);
  cpuDelay(20000000);
  *laddr = 0x800; //SYNC phase alingment, no use here, but should not hurt to keep either
  cpuDelay(10000000);
  cpuDelay(100);
 
  //  FiberMeas(islot);
  //  cpuDelay(0x10000);

  // A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd+0x50,&laddr);
  *laddr = 0x1f1f1f1f;
  cpuDelay(100000);

  sysBusToLocalAdrs(0x39,RegAdd+0x78,&laddr);  //sync 
  *laddr = 0xdd;    // reset 
  cpuDelay(0x1000000);

  // Set the TI data format
  sysBusToLocalAdrs(0x39,RegAdd+0x18,&laddr); 
  *laddr = 0x60000003; 

  //set the Block size
  sysBusToLocalAdrs(0x39,RegAdd+0x14,&laddr); 
  *laddr = (0xff & BlockSize);
  //set the CrateID
  sysBusToLocalAdrs(0x39,RegAdd,&laddr); 
  *laddr = (0xff & CrateID);
  cpuDelay(100000);

  sysBusToLocalAdrs(0x39,RegAdd+0x28,&laddr);	/* trigger interface */
  *laddr = 0x80;  // TS feed_back busy enabled
  cpuDelay(0x1000);

  sysBusToLocalAdrs(0x39,RegAdd+0x0C,&laddr);	/* trigger interface */
  *laddr = 0x0f000f00;  // trigger pulse width=64ns, delay 0
  cpuDelay(0x1000);
  sysBusToLocalAdrs(0x39,RegAdd+0x30,&laddr);	/* trigger interface */
  *laddr = 0x00;  // trigger prescale
  cpuDelay(0x1000);

  sysBusToLocalAdrs(0x39,RegAdd+0x10,&laddr);		/* trigger interface */
  *laddr = (0x08000000+((islot<<23)&0x0f800000)); //A32 base address setup
  cpuDelay(0x1000);

  sysBusToLocalAdrs(0x39,RegAdd+0x1C,&laddr);		/* trigger interface */
  *laddr = 0x000011; //A32 base address setup
  cpuDelay(0x1000);
  printf(" VME setting %08x \n", *laddr);

  //set the trigger link to IDLE mode
  sysBusToLocalAdrs(0x39,RegAdd+0x78,&laddr);		/* trigger interface */
  *laddr = 0x77;  //WriteStart: reset the buffer write counter, and disable the trigger data
  cpuDelay(1000000);
  *laddr = 0x77;  //just in case that the sync is later than TrgData
  cpuDelay(0x100000);

  // Reset the trigger link
  sysBusToLocalAdrs(0x39,RegAdd+0x100, &laddr);
  *laddr = 0x400; //MGT sync
  cpuDelay(0x1000000);

  sysBusToLocalAdrs(0x39,RegAdd+0x20, &laddr);
  *laddr = 0x94; //enable Random, VME and TImaster internal loopback
  cpuDelay(1000);
  printf (" Trigger source set to %08x \n",*laddr);
  cpuDelay(0x10000);
  sysBusToLocalAdrs(0x39,RegAdd+0x34,&laddr);	//TS threshold and IRQ
  *laddr = 0x22;
  printf(" TIM block number threshold %08x", *laddr);
  sysBusToLocalAdrs(0x39,RegAdd+0x08, &laddr);
  *laddr = 0x5C7;  //irq level 5, id=0xC7
  cpuDelay(0x1000);

  // Reset
  sysBusToLocalAdrs(0x39,RegAdd+0x78, &laddr);
  *laddr = 0xdd;

  //Start the clock monitoring
  sysBusToLocalAdrs(0x39,RegAdd+0x9c, &laddr);
  *laddr = 0x71; //set TI in 'running mode"
  sysBusToLocalAdrs(0x39,RegAdd, &laddr);
  printf (" \n The TImaster state is %08x in slot# %d \n", *laddr, islot);
  printf (" \n TImaster Trigger/DAQ is set in slot# %d \n",islot);
}


// **** TI master Fiber Loop Back setting, to be discontinued
void TImasterFLB(unsigned int islot, unsigned int BlockSize, unsigned int CrateID)
{
  unsigned long *laddr;
  unsigned long RegAdd, OldValue;

  //FPGA reload
  EMFPGAreload(islot);
  cpuDelay(20000000);

  RegAdd = ((islot<<19)&0xf80000);

  //TI clock setup
  sysBusToLocalAdrs(0x39,RegAdd+0x2C,&laddr);
  *laddr = 0x0000;  //Oscillator input clock is selected
  cpuDelay(0x50000);
  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);
  *laddr = 0x100;  //250MHz DCM reset;
  cpuDelay(0x50000);
  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);
  *laddr = 0x200;  //125 MHz DCm reset
  cpuDelay(0x50000);

  sysBusToLocalAdrs(0x39,RegAdd+0x7C,&laddr);		/* SYNC interface */
  *laddr = 0x54;  // Sync delay (0x54) before being serialized
  cpuDelay(0x100000);
  sysBusToLocalAdrs(0x39,RegAdd+0x80,&laddr);		/* Reset pulse width */
  *laddr = 0x2f;  //Sync (reset) width (0xf) 
  cpuDelay(0x100000);

  // Enable the Fiber transmitters as the default might be OFF
  sysBusToLocalAdrs(0x39,RegAdd+0x04,&laddr);
  *laddr = 0x00f1;  // Enable fiber #1 and #5, #6, #7 and #8
  cpuDelay(5000000);

  // set sync source
  sysBusToLocalAdrs(0x39,RegAdd+0x24,&laddr); 
  *laddr = 0x02; 
  cpuDelay(0x50000);

  //FPGA IOdelay reset
  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);  //sync 
  *laddr = 0x4000;    // reset IODELAY
  cpuDelay(10000);
  cpuDelay(20000000);
  *laddr = 0x800; //SYNC phase alingment
  cpuDelay(10000000);
  cpuDelay(100);
 
  FiberMeas(islot);
  cpuDelay(0x10000);

  /* A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd+0x50,&laddr);
  *laddr = 0x1f1f1f1f;
  cpuDelay(100000);
  */

  sysBusToLocalAdrs(0x39,RegAdd+0x78,&laddr);  //sync 
  *laddr = 0xdd;    // reset 
  cpuDelay(0x1000000);

  // Set the TI data format
  sysBusToLocalAdrs(0x39,RegAdd+0x18,&laddr); 
  *laddr = 0x60000003; 

  //set the Block size
  sysBusToLocalAdrs(0x39,RegAdd+0x14,&laddr); 
  *laddr = (0xff & BlockSize);
  //set the CrateID
  sysBusToLocalAdrs(0x39,RegAdd,&laddr); 
  *laddr = (0xff & CrateID);
  cpuDelay(100000);

  sysBusToLocalAdrs(0x39,RegAdd+0x28,&laddr);	/* trigger interface */
  *laddr = 0x0080;  // TImaster internal feed back BUSY
  cpuDelay(0x1000);

  sysBusToLocalAdrs(0x39,RegAdd+0x0C,&laddr);	/* trigger pulse width, delay */
  *laddr = 0x0f000f00;  // trigger pulse width=64ns, delay 0
  cpuDelay(0x1000);
  sysBusToLocalAdrs(0x39,RegAdd+0x30,&laddr);	/* trigger prescale */
  *laddr = 0x01;  // trigger prescale
  cpuDelay(0x1000);

  sysBusToLocalAdrs(0x39,RegAdd+0x10,&laddr);		/* A32 address */
  *laddr = (0x08000000+((islot<<23)&0x0f800000)); //A32 base address setup
  cpuDelay(0x1000);

  sysBusToLocalAdrs(0x39,RegAdd+0x1C,&laddr);		/* trigger interface */
  *laddr = 0x000011; //A32 base address setup
  cpuDelay(0x1000);

  //set the trigger link to IDLE mode
  sysBusToLocalAdrs(0x39,RegAdd+0x78,&laddr);		/* trigger interface */
  *laddr = 0x77;  //WriteStart: reset the buffer write counter, and disable the trigger data
  cpuDelay(1000000);
  *laddr = 0x77;  //just in case that the sync is later than TrgData
  cpuDelay(0x100000);

  // reset the trigger link
  sysBusToLocalAdrs(0x39,RegAdd+0x100, &laddr);
  *laddr = 0x400; //MGT sync
  cpuDelay(0x1000000);

  sysBusToLocalAdrs(0x39,RegAdd+0x20, &laddr);
  *laddr = 0x92;  //enable Random, VME and external fiber loopback
  cpuDelay(0x1000);
  printf(" Trigger source is set to %08x \n", *laddr);
  sysBusToLocalAdrs(0x39,RegAdd+0x34,&laddr);	//TS threshold and IRQ (block threshold)
  *laddr = 0x22;
  sysBusToLocalAdrs(0x39,RegAdd+0x08, &laddr);
  *laddr = 0x5C7;  //irq level 5, id=0xC7
  cpuDelay(0x1000);

  // reset
  sysBusToLocalAdrs(0x39, RegAdd+0x78, &laddr);
  *laddr = 0xdd;

  //Start the clock monitoring
  sysBusToLocalAdrs(0x39,RegAdd+0x9c, &laddr);
  *laddr = 0x71; //set TI in 'running mode"
  sysBusToLocalAdrs(0x39,RegAdd, &laddr);
  printf (" The TImaster state is %08x in slot# %d \n", *laddr, islot);

  printf (" \n TImaster Trigger/DAQ is set in slot# %d \n",islot);
}

void FiberMeas(unsigned int islot)
{
  unsigned long *laddr;
  unsigned long fiberLatency, syncDelay;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  // A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);		/* trigger interface */
  *laddr = 0x4000;  // reset the IODELAY
  cpuDelay(0x100000);
  *laddr = 0x2000;  // auto adjust the return signal phase
  cpuDelay(10000000);
  *laddr = 0x8000;  // measure the fiber latency
  cpuDelay(10000000);

  sysBusToLocalAdrs(0x39,RegAdd+0xA0,&laddr);		/* trigger interface */
  printf("Fiber Latency is %x\n",*laddr);

  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);		/* trigger interface */
  *laddr = 0x800;   // auto adjust the sync phase for HFBR#1
  cpuDelay(10000000);
  //disable this for now:   *laddr = 0x1000;  // auto adjust the sync phase for HFBR#5
  cpuDelay(10000000);

  sysBusToLocalAdrs(0x39,RegAdd+0xA0,&laddr);		/* trigger interface */
  fiberLatency = *laddr;  //fiber latency measurement result
  syncDelay = (0xbf-(((fiberLatency>>23)&0x1ff)/2));
  syncDelay=(syncDelay<<8)&0xff00;  //set the sync delay according to the fiber latency
  cpuDelay(0x10000);

  sysBusToLocalAdrs(0x39,RegAdd+0x50,&laddr);		/* trigger interface */
  *laddr = syncDelay;
  cpuDelay(0x10000);
  syncDelay= *laddr;
  printf (" \n The fiber latency of 0xA0 is: %x in slot# %d \n", fiberLatency, islot );
  printf (" \n The sync latency of 0x50 is: %x in slot# %d \n",syncDelay, islot);
}

unsigned long PROMchipcode(unsigned int islot)
{
  unsigned long *laddr;
  unsigned long Dataword;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  // A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);		/* reset */
  *laddr = 0x04;
  sysBusToLocalAdrs(0x39,RegAdd+0x1003c,&laddr);       
  *laddr = 0x0;                                         // Reset_idle
  sysBusToLocalAdrs(0x39,RegAdd+0x10f2c,&laddr);
  *laddr = 0x00FE;                                       // load the Chipcode Enable
  sysBusToLocalAdrs(0x39,RegAdd+0x11f1c,&laddr);
  *laddr = 0x00;                                        // shift in 32-bit of data
  Dataword = *laddr;
  printf (" \n PROM ChipCode is %x in slot# %d \n", Dataword, islot);
  return Dataword;
}
void FPGAreload(unsigned int islot)
{
  unsigned long *laddr;
  unsigned long Dataword;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  // A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd+0x100,&laddr);		/* reset */
  *laddr = 0x04;
  sysBusToLocalAdrs(0x39,RegAdd+0x1003c,&laddr);       
  *laddr = 0x0;                                         // Reset_idle
  sysBusToLocalAdrs(0x39,RegAdd+0x10f2c,&laddr);
  *laddr = 0x00EE;                                       // load the CONFIG command
  //  sysBusToLocalAdrs(0x39,RegAdd+0x11f1c,&laddr);
  //  *laddr = 0x00;                                        // shift in 32-bit of data
  printf (" \n FPGA Re-Load in slot# %d ! \n", islot);
}

void FPGAall(void)
{
  EMFPGAreload(20);  //reload TS
  cpuDelay(10000000);
  EMFPGAreload(18);  //reload TD
  cpuDelay(1000000);
  EMFPGAreload(17);
  cpuDelay(1000);
  cpuDelay(10000000);
  EMFPGAreload(5);   //reload TIs
  EMFPGAreload(7);
  EMFPGAreload(9);
  cpuDelay(1000);
  cpuDelay(10000000);
  EMFPGAreload(20);  //reload TS again, 
  cpuDelay(10000000);
}


void TrgDAQSet(unsigned int islot, unsigned int BlockSize, unsigned int CrateID)
{
  unsigned long *laddr;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  // A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd,&laddr);		/* trigger interface */
  *laddr = 0x62000000 + (0xff00&(BlockSize<<8)) + (0xff&CrateID);
  cpuDelay(0x1000);
  sysBusToLocalAdrs(0x39,RegAdd+4,&laddr);	/* trigger interface */
  *laddr = 0x00000011;  //no HFBR busy enabled, transceiver #1, #5 are enabled
  cpuDelay(0x1000);
  sysBusToLocalAdrs(0x39,RegAdd+0xC,&laddr);	/* trigger interface */
  *laddr = 0x07000700;  //prescale=1, trigger pulse width=32ns, delay 0
  cpuDelay(0x1000);
  sysBusToLocalAdrs(0x39,RegAdd+0x10,&laddr);		/* trigger interface */
  *laddr = (0x08000010+ ((islot<<23)&0x0f800000)); //A32 base address setup
  cpuDelay(0x1000);
  printf (" \n Trigger/DAQ is set in slot# %d \n", islot);
}


void TSSet(unsigned int islot, unsigned int BlockSize, unsigned int CrateID)
{
  unsigned long *laddr;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  // A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd+0x1C,&laddr);
  *laddr = 0x7f7f7f7f;    // set the SYNC delay to the maximum without measuring the delay
  cpuDelay(0x1000);
  sysBusToLocalAdrs(0x39,RegAdd,&laddr);		/* trigger interface */
  *laddr = 0x70000000 + (0xff00&(BlockSize<<8)) + (0xff&CrateID);  //loopback sync enabled
  cpuDelay(0x1000);
  sysBusToLocalAdrs(0x39,RegAdd+4,&laddr);	/* trigger interface */
  *laddr = 0x00820000;  //Feedback busy enabled, SW#B busy input enabled
  cpuDelay(0x1000);
  sysBusToLocalAdrs(0x39,RegAdd+0xC,&laddr);	/* trigger interface */
  *laddr = 0x07000700;  //prescale=1, trigger pulse width=32ns, delay 0
  cpuDelay(0x1000);
  sysBusToLocalAdrs(0x39,RegAdd+0x10,&laddr);		/* trigger interface */
  *laddr = (0x08000010+((islot<<23)&0x0f800000)); //A32 base address setup
  cpuDelay(0x1000);
  TrgLinkReset(islot);
  cpuDelay(0x10000);
  TrgSrcEnable(islot,0x92);
  cpuDelay(0x1000);
  sysBusToLocalAdrs(0x39,RegAdd+0x8,&laddr);	//TS threshold and IRQ
  *laddr = 0xff0005b7;  //threshold 0x88, irq level 5, id=0xb7
  cpuDelay(0x1000);

  sysBusToLocalAdrs(0x39,RegAdd+0x900,&laddr);	//reset the counters through SYNC
  *laddr = 0xDD; //generic SYNC reset
  cpuDelay(0x1000);

  //  sysBusToLocalAdrs(0x39,RegAdd+0x804,&laddr);	// VME trigger
  //  *laddr = 0x91950100;  // 0x200 triggers at ~2Hz

  printf (" \n TIMaster Trigger/DAQ is set in slot# %d \n",islot);
}


void TrgStart(unsigned int islot)
{
  unsigned long *laddr;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);

  // MGT reset
  sysBusToLocalAdrs(0x39,RegAdd+0x78,&laddr);	// VME trigger
  *laddr = 0x22;  // MGT 'CLKSYN'
  cpuDelay(10000000);

  //Trigger buffer init
  TrgLinkReset(islot);
  cpuDelay(0x100000);

  sysBusToLocalAdrs(0x39,RegAdd+0x8c,&laddr);	// VME trigger
  *laddr = 0xa1950020;  // 0x100 triggers
}

void TrgLinkReset(unsigned int islot)
{
  unsigned long *laddr;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  // A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd+0x78,&laddr);		/* trigger interface */
  *laddr = 0x77;  //WriteStart: reset the buffer write counter, and disable the trigger data
  cpuDelay(1000000);
  *laddr = 0x77;  //just in case that the sync is later than TrgData
  cpuDelay(0x100000);
  sysBusToLocalAdrs(0x39,RegAdd+0x80,&laddr);		/* trigger interface */
  *laddr = 0x2f;  //Sync pulse width (0x2f) after being decoded
  cpuDelay(0x100000);
   sysBusToLocalAdrs(0x39,RegAdd+0x7c,&laddr);		/* trigger interface */
  *laddr = 0x54;  // Sync delay (0x54) before being serialized
  cpuDelay(0x100000);
  sysBusToLocalAdrs(0x39,RegAdd+0x78,&laddr);		/* trigger interface */
  *laddr = 0x55;  //ReadStart: Start the readbuffer and enable the TrgData
  cpuDelay(0x1000000);
  printf (" \n The Trigger Data link is reset (set by) slot# %d \n", islot);
  *laddr=0xdd;
  cpuDelay(100000);

}

void TrgSrcEnable(unsigned int islot, unsigned int TrgSrc)
{
  unsigned long *laddr;
  unsigned long TrgDaqSetting;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  // A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd,&laddr);		/* trigger interface */
  TrgDaqSetting = *laddr;
  printf(" The Trigger_DAQ register is %x \n",TrgDaqSetting);
  sysBusToLocalAdrs(0x39,RegAdd,&laddr);
  *laddr = (0xffff & TrgSrc);
  cpuDelay(10000);
}


// TImaster front panel trigger table setup
void TrgTblLoad(unsigned int islot)
{
	unsigned long *laddr;
	unsigned long RegAdd;

	RegAdd = ((islot<<19)&0xf80000);

	sysBusToLocalAdrs(0x39, RegAdd+0x8C0, &laddr);
	*laddr = 0x0c0c0c00;
	sysBusToLocalAdrs(0x39, RegAdd+0x8C4, &laddr);
	*laddr = 0x0c0c0c0c;
	sysBusToLocalAdrs(0x39, RegAdd+0x8C8, &laddr);
	*laddr = 0xccccccc0;
	sysBusToLocalAdrs(0x39, RegAdd+0x8CC, &laddr);
	*laddr = 0xCCCCCCCC;
	sysBusToLocalAdrs(0x39, RegAdd+0x8D0, &laddr);
	*laddr = 0xCCCCCCC0;
	sysBusToLocalAdrs(0x39, RegAdd+0x8D4, &laddr);
	*laddr = 0xCCCCCCCC;
	sysBusToLocalAdrs(0x39, RegAdd+0x8D8, &laddr);
	*laddr = 0xCCCCCCC0;
	sysBusToLocalAdrs(0x39, RegAdd+0x8DC, &laddr);
	*laddr = 0xCCCCCCCC;
	sysBusToLocalAdrs(0x39, RegAdd+0x8E0, &laddr);
	*laddr = 0xCCCCCCC0;
	sysBusToLocalAdrs(0x39, RegAdd+0x8E4, &laddr);
	*laddr = 0xCCCCCCCC;
	sysBusToLocalAdrs(0x39, RegAdd+0x8E8, &laddr);
	*laddr = 0xCCCCCCC0;
	sysBusToLocalAdrs(0x39, RegAdd+0x8EC, &laddr);
	*laddr = 0xCCCCCCCC;
	sysBusToLocalAdrs(0x39, RegAdd+0x8F0, &laddr);
	*laddr = 0xCCCCCCC0;
	sysBusToLocalAdrs(0x39, RegAdd+0x8F4, &laddr);
	*laddr = 0xCCCCCCCC;
	sysBusToLocalAdrs(0x39, RegAdd+0x8F8, &laddr);
	*laddr = 0xCCCCCCC0;
	sysBusToLocalAdrs(0x39, RegAdd+0x8FC, &laddr);
	*laddr = 0xCCCCCCCC;
}

void SubTSReadAll(unsigned int islot, unsigned int words)
{
  SubTSRead(islot, 1, words);
  SubTSRead(islot, 2, words);
  SubTSRead(islot, 3, words);
  SubTSRead(islot, 4, words);
}

void SubTSRead(unsigned int islot, unsigned int iSubTS, unsigned int words) 
{
  unsigned long *laddr;
  int i;
  unsigned long RegAdd;
  unsigned long DataAdd;
  //A24 read

        RegAdd = ((islot<<19)&0xf80000) +(((iSubTS*2-1)<<8)&0x700) +0x50;

    	sysBusToLocalAdrs(0x39, RegAdd, &laddr);

	for (i = 0; i< words; i++)
	  {printf(" TS slot# %02x, SubTS# %01x, Data: %08x \n",islot, iSubTS, *laddr);}

}

void tidsRead(unsigned int islot, unsigned long words)  //number of words to be readout
{
  unsigned long *laddr;
  int i;
  unsigned long RegAdd;
  unsigned long DataAdd;
  //A32 read

        RegAdd = ((islot<<19)&0xf80000);
	DataAdd = 0x08000000 + ((islot<<23)&0x0f800000);

    	sysBusToLocalAdrs(0x39, RegAdd+0x10, &laddr);
	printf(" laddr %08x \n",laddr);
	*laddr = DataAdd + 0x10; 

	sysBusToLocalAdrs(0x09, DataAdd, &laddr);
	for (i=0;i<words;i++) {
	printf("Data Readout at laddr: %08x is: %08x \n",laddr, *laddr);
	}
}

void cpuDelay(unsigned long delays)
{
  unsigned long time_0, time_1, time, diff;
  time_0 = sysTimeBaseLGet();
  do
    {
      time_1 = sysTimeBaseLGet();
      time = sysTimeBaseLGet();
      //      printf("Time base: %x , next call: %x , second call: %x \n",time_0,time_1, time);
      diff = time-time_0;
    } while (diff <delays);
}

void tidsBRead(unsigned int islot, unsigned long Nbytes)  // TS block read, Nbytes to be readout
{
  STATUS status;
  unsigned long tid_data_adr, dma_bytes, bytes_left,i;
  volatile char *DmaAdr;
  volatile char *VmeAdrs;
  volatile long *databuf;
  volatile long ii,jj, header0, event0;
  volatile long dataword;
  unsigned long *laddr;
  unsigned long RegAdd, DataAdd;
  FILE *fileData;

  RegAdd = ((islot<<19)&0xf80000);
  DataAdd =0x08000000 + ((islot<<23)&0x0f800000);

  tid_data_adr=DataAdd;    //VME A32 address
  sysBusToLocalAdrs(0x39, RegAdd+0x10, &laddr);
  *laddr = (DataAdd+0x10);

  usrVmeDmaConfig(2,5,1); //A32, 2ESS at 267MHz
  dma_bytes=Nbytes;
  DmaAdr = malloc(Nbytes);
  VmeAdrs=(volatile char *)tid_data_adr;
  status = sysVmeDmaSend(DmaAdr,VmeAdrs,dma_bytes,0);  // block read

    bytes_left=0;
    bytes_left = sysVmeDmaDone(0,1);
    //take a  break
    //   cpuDelay(30000); // delay 1 ms

  printf(" Bytes to read: %x, bytes left: %x ", dma_bytes, bytes_left);

  fileData = fopen("tidsBlk.dat","w");
  databuf = DmaAdr;
  for (i=0;i<dma_bytes/4;i++)
    {
      fprintf(fileData," %8x \n",*(databuf+i));
    }
  fclose(fileData);
 
  /* data check

  header0=*(databuf);
  event0=0xffff&(*(databuf+1));
  printf(" Header0: %x ", header0);
  printf(" Event0: %x \n", event0);
  for (ii=0;ii<dma_bytes/56;ii++) {
    //    if ((ii%5) == 0) printf("\n");
    dataword= *(databuf+ii*14);
    if (!(dataword-header0)==(0xff00&(ii*256))) {printf("**** header %x wrong %x \n",ii,dataword);}
    //    else  {printf("H");}

    for (jj=0;jj<5;jj++) {
      dataword = *(databuf+ii*14+jj*2+1);
      if (!(((dataword&0xffff)-event0)==(0xffff&(ii*5+jj)))) {printf("***** Event ii: %x jj: %x Wrong: %x \n",ii,jj,dataword);}
      //else {printf("T");}

      dataword = *(databuf+ii*14+jj*2+2);
      if (!(dataword==0xaaaa9999)) {printf("****** Event ii: %x jj: %x Wrong: %x \n",ii,jj,dataword);}
      //else  {printf("S");}
    }
  }
  //  printf("\n The End \n");  */

}
unsigned int tidsBERead(unsigned int islot)  // TS block read, single board, Bus_error ending
{
  STATUS status;
  unsigned long tid_data_adr, dma_bytes, bytes_left,i;
  volatile char *DmaAdr;
  volatile char *VmeAdrs;
  volatile long *databuf;
  volatile long ii,jj, header0, event0;
  volatile long dataword;
  unsigned long *laddr;
  unsigned long RegAdd, DataAdd;

  FILE *fileData;

  RegAdd = ((islot<<19)&0xf80000);
  DataAdd = 0x08000000+((islot<<23)&0x0f800000);

  tid_data_adr=DataAdd;    //VME A32 address
  usrVmeDmaConfig(2,5,1); //A32, 2ESS at 267MHz
 
  sysBusToLocalAdrs(0x39, RegAdd+0x10, &laddr);
  *laddr = DataAdd+0x11;  // A32 with Bus_error_enable

  dma_bytes=15680;
  DmaAdr = malloc(15680);
  VmeAdrs=(volatile char *)tid_data_adr;
  status = sysVmeDmaSend(DmaAdr,VmeAdrs,dma_bytes,0);  // block read

    bytes_left=0;
    bytes_left = sysVmeDmaDone(0,1);
    //take a  break
    //   cpuDelay(30000); // delay 1 ms

  printf(" Bytes to read: %x, bytes left: %x ", dma_bytes, bytes_left);

  fileData = fopen("tidsBE.dat","w");
  databuf = DmaAdr;
  for (i=0;i<(dma_bytes-bytes_left)/4;i++)
    {
      fprintf(fileData," %8x \n",*(databuf+i));
    }
  fclose(fileData);
  return (dma_bytes - bytes_left);
}
void tidsBE4Read(unsigned int islot)  // TS block read, single board, Bus_error ending
{
  STATUS status;
  unsigned long tid_data_adr, dma_bytes, bytes_left,i;
  volatile char *DmaAdr;
  volatile char *VmeAdrs;
  volatile long *databuf;
  volatile long ii,jj, header0, event0;
  volatile long dataword;
  unsigned long *laddr;
  FILE *fileData;
  unsigned long RegAdd, DataAdd;
  RegAdd = ((islot<<19)&0xf80000);
  DataAdd = 0x08000000 + ((islot<<23)&0x0f800000);

  tid_data_adr=DataAdd;    //VME A32 address
  usrVmeDmaConfig(2,4,1); //A32, 2EVME at 267MHz
 
  sysBusToLocalAdrs(0x39, RegAdd+0x10, &laddr);
  *laddr = DataAdd + 0x11;  // A32 with Bus_error_enable

  dma_bytes=15680;
  DmaAdr = malloc(15680);
  VmeAdrs=(volatile char *)tid_data_adr;
  status = sysVmeDmaSend(DmaAdr,VmeAdrs,dma_bytes,0);  // block read

    bytes_left=0;
    bytes_left = sysVmeDmaDone(0,1);
    //take a  break
    //   cpuDelay(30000); // delay 1 ms

  printf(" Bytes to read: %x, bytes left: %x ", dma_bytes, bytes_left);

  fileData = fopen("tsE4.dat","w");
  databuf = DmaAdr;
  for (i=0;i<(dma_bytes-bytes_left)/4;i++)
    {
      fprintf(fileData," %8x \n",*(databuf+i));
    }
  fclose(fileData);
}


void tidsBT2Read(unsigned int islot)  // TS block read in multi-board case
{
  STATUS status;
  unsigned long tid_data_adr, dma_bytes, bytes_left,i;
  volatile char *DmaAdr;
  volatile char *VmeAdrs;
  volatile long *databuf;
  volatile long ii,jj, header0, event0;
  volatile long dataword;
  unsigned long *laddr;
  FILE *fileData;
  unsigned long RegAdd, DataAdd;
  RegAdd = ((islot<<19)&0xf80000);
  DataAdd = 0x08000000+((islot<<23)&0x0f800000);
  tid_data_adr=DataAdd;    //VME A32 address, MB min: 0x08, MB max: 0x11
  usrVmeDmaConfig(2,2,1); //A32, BLT32, at 267MHz
  sysBusToLocalAdrs(0x39, RegAdd+0x10, &laddr);
  *laddr = DataAdd+0x7845c;
  sysBusToLocalAdrs(0x39, RegAdd+0x04, &laddr);
  dataword = *laddr;
  dataword = (dataword&0xfffff3ff)+ 0x0400; //first board, not last board, no_token_input
  *laddr=dataword;
  sysBusToLocalAdrs(0x39, RegAdd+0x100, &laddr);
  *laddr = 0x00010000;  //take token


  dma_bytes=15680;
  DmaAdr = malloc(15700);
  VmeAdrs=(volatile char *)tid_data_adr;
  status = sysVmeDmaSend(DmaAdr,VmeAdrs,dma_bytes,0);  // block read

    bytes_left=0;
    bytes_left = sysVmeDmaDone(0,1);
    //take a  break
    //   cpuDelay(30000); // delay 1 ms

  printf(" Bytes to read: %x, bytes left: %x ", dma_bytes, bytes_left);

  fileData = fopen("tsT2.dat","w");
  databuf = DmaAdr;
  for (i=0;i<(dma_bytes-bytes_left)/4;i++)
    {
      fprintf(fileData," %8x \n",*(databuf+i));
    }
  fclose(fileData);
}

void tidsBT3Read(unsigned int islot)  // TS block read in multi-board case
{
  STATUS status;
  unsigned long tid_data_adr, dma_bytes, bytes_left,i;
  volatile char *DmaAdr;
  volatile char *VmeAdrs;
  volatile long *databuf;
  volatile long ii,jj, header0, event0;
  volatile long dataword;
  unsigned long *laddr;
  FILE *fileData;
  unsigned long RegAdd, DataAdd;
  RegAdd = ((islot<<19)&0xf8000);
  DataAdd = 0x08000000 + ((islot<<23)&0x0f800000);

  tid_data_adr=DataAdd;  //VME A32 address,
  usrVmeDmaConfig(2,3,1); //A32, D64 at 267MHz
  sysBusToLocalAdrs(0x39, RegAdd+0x10, &laddr);
  *laddr = 0x07845c+DataAdd;
  sysBusToLocalAdrs(0x39, RegAdd+0x04, &laddr);
   dataword = *laddr;
  *laddr = ((dataword&0xfffff3ff)+ 0x0400); //first board, not last board, no_token_input
  sysBusToLocalAdrs(0x39, RegAdd+0x100, &laddr);
  *laddr = 0x00010000;  //take token


  dma_bytes=15680;
  DmaAdr = malloc(15700);
  VmeAdrs=(volatile char *)tid_data_adr;
  status = sysVmeDmaSend(DmaAdr,VmeAdrs,dma_bytes,0);  // block read

    bytes_left=0;
    bytes_left = sysVmeDmaDone(0,1);
    //take a  break
    //   cpuDelay(30000); // delay 1 ms

  printf(" Bytes to read: %x, bytes left: %x ", dma_bytes, bytes_left);

  fileData = fopen("tsT3.dat","w");
  databuf = DmaAdr;
  for (i=0;i<(dma_bytes-bytes_left)/4;i++)
    {
      fprintf(fileData," %8x \n",*(databuf+i));
    }
  fclose(fileData);
}

void tidsBT4Read(unsigned int islot)  // TS block read in multi-board case
{
  STATUS status;
  unsigned long tid_data_adr, dma_bytes, bytes_left,i;
  volatile char *DmaAdr;
  volatile char *VmeAdrs;
  volatile long *databuf;
  volatile long ii,jj, header0, event0;
  volatile long dataword;
  unsigned long *laddr;
  FILE *fileData;
  unsigned long RegAdd, DataAdd;
  RegAdd = ((islot<<19)&0xf80000);
  DataAdd = 0x08000000 + ((islot<<23)&0x0f800000);
  tid_data_adr= DataAdd;    //VME A32 address
  usrVmeDmaConfig(2,4,1); //A32, 2EVME at 267MHz
  sysBusToLocalAdrs(0x39, RegAdd+0x10, &laddr);
  *laddr = 0x7845c+DataAdd;
  sysBusToLocalAdrs(0x39, RegAdd+0x04, &laddr);

  dataword = *laddr;
  *laddr = ((dataword&0xfffff3ff)+ 0x0400); //first board, not last board, no_token_input
  sysBusToLocalAdrs(0x39, RegAdd+0x100, &laddr);
  *laddr = 0x00010000;  //take token


  dma_bytes=15680;
  DmaAdr = malloc(15700);
  VmeAdrs=(volatile char *)tid_data_adr;
  status = sysVmeDmaSend(DmaAdr,VmeAdrs,dma_bytes,0);  // block read

    bytes_left=0;
    bytes_left = sysVmeDmaDone(0,1);
    //take a  break
    //   cpuDelay(30000); // delay 1 ms

  printf(" Bytes to read: %x, bytes left: %x ", dma_bytes, bytes_left);

  fileData = fopen("tsT4.dat","w");
  databuf = DmaAdr;
  for (i=0;i<(dma_bytes-bytes_left)/4;i++)
    {
      fprintf(fileData," %8x \n",*(databuf+i));
    }
  fclose(fileData);
}

void EmergencyS(unsigned int islot, unsigned int jtagType, unsigned int numBits, unsigned long jtagData)
{
  unsigned long *laddr;
  unsigned int iloop;
  unsigned long shData;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  // A24 buffer write
  sysBusToLocalAdrs(0x39,RegAdd+0x0FFFC,&laddr);	//Emergency A24 address

  printf(" \n laddr is %08x\n",laddr);
  laddr = 0x9000fffc + RegAdd ;
   printf("\n laddr is redefined as %08x \n",laddr);

  if (jtagType == 0) //JTAG reset, TMS high for 5 clcoks, and low for 1 clock;
    {
      for (iloop=0; iloop<5; iloop++)
	{
	  *laddr = 1;
	}
      *laddr = 0;
    }
  else if (jtagType == 1) // JTAG instruction shift, for now, limit the numBits to 32 (fit in LONG)
    {
      // Shift_IR header:
      *laddr = 0;
      *laddr = 1;
      *laddr = 1;
      *laddr = 0;
      *laddr = 0;
      for (iloop =0; iloop <numBits; iloop++)
	{ 
	  shData = ((jtagData >> iloop )<<1) &0x2;
	  if (iloop == numBits -1) shData = shData +1;  //set the TMS high for last bit to exit Shift_IR
	  *laddr = shData;
	}
      // shift _IR tail
      *laddr = 1;  // update instruction register
      *laddr = 0;  // back to the Run_test/Idle
    }
  else if (jtagType == 2)  // JTAG data shift, for now, limit the numBits to 32
    {
      //shift_DR header
      *laddr = 0;
      *laddr = 1;
      *laddr = 0;
      *laddr = 0;
      for (iloop =0; iloop <numBits; iloop++)
	{ 
	  shData = ((jtagData >> iloop )<<1) &0x2;
	  if (iloop == numBits -1) shData = shData +1;  //set the TMS high for last bit to exit Shift_DR
	  *laddr = shData;
	}
      // shift _DR tail
      *laddr = 1;  // update Data_Register
      *laddr = 0;  // back to the Run_test/Idle
    }
  else
    {
      printf( "\n JTAG type %d unrecognized \n",jtagType);
    }

  printf (" \n Emergency command executed \n");
}

void EmergencyTest(unsigned int jtagType, unsigned int numBits, unsigned long *jtagData)
{
  int numWord, i;
  printf("type: %x, num of Bits: %x, data: \n",jtagType, numBits);
  numWord = (numBits-1)/32+1;
  for (i=0; i<numWord; i++)
    {
      printf("%08x",jtagData[numWord-i-1]);
    }
  printf("\n");
}

void Emergency(unsigned int islot, unsigned int jtagType, unsigned int numBits, unsigned long *jtagData)
{
  unsigned long *laddr;
  unsigned int iloop, iword, ibit;
  unsigned long shData;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  /*  int numWord, i;
  printf("type: %x, num of Bits: %x, data: \n",jtagType, numBits);
  numWord = (numBits-1)/32+1;
  for (i=0; i<numWord; i++)
    {
      printf("%08x",jtagData[numWord-i-1]);
    }
  printf("\n");
  */

  // A24 buffer write
  //  sysBusToLocalAdrs(0x39,RegAdd+0x0FFFC,&laddr);	//Emergency A24 address

  //  printf(" \n laddr is %08x\n",laddr);

  laddr = 0x9000fffc + RegAdd;  // for MVME6100 controller
  //  printf("\n laddr is redefined as %08x \n",laddr);

  if (jtagType == 0) //JTAG reset, TMS high for 5 clcoks, and low for 1 clock;
    {
      for (iloop=0; iloop<5; iloop++)
	{
	  *laddr = 1;
	}
      *laddr = 0;
    }
  else if (jtagType == 1) // JTAG instruction shift
    {
      // Shift_IR header:
      *laddr = 0;
      *laddr = 1;
      *laddr = 1;
      *laddr = 0;
      *laddr = 0;
      for (iloop =0; iloop <numBits; iloop++)
	{ 
	  iword = iloop/32;
	  ibit = iloop%32;
	  shData = ((jtagData[iword] >> ibit )<<1) &0x2;
	  if (iloop == numBits -1) shData = shData +1;  //set the TMS high for last bit to exit Shift_IR
	  *laddr = shData;
	}
      // shift _IR tail
      *laddr = 1;  // update instruction register
      *laddr = 0;  // back to the Run_test/Idle
    }
  else if (jtagType == 2)  // JTAG data shift
    {
      //shift_DR header
      *laddr = 0;
      *laddr = 1;
      *laddr = 0;
      *laddr = 0;
      for (iloop =0; iloop <numBits; iloop++)
	{ 
	  iword = iloop/32;
	  ibit = iloop%32;
	  shData = ((jtagData[iword] >> ibit )<<1) &0x2;
	  if (iloop == numBits -1) shData = shData +1;  //set the TMS high for last bit to exit Shift_DR
	  *laddr = shData;
	}
      // shift _DR tail
      *laddr = 1;  // update Data_Register
      *laddr = 0;  // back to the Run_test/Idle
    }
  else if (jtagType == 3) // JTAG instruction shift, stop at IR-PAUSE state, though, it started from IDLE
    {
      // Shift_IR header:
      *laddr = 0;
      *laddr = 1;
      *laddr = 1;
      *laddr = 0;
      *laddr = 0;
      for (iloop =0; iloop <numBits; iloop++)
	{ 
	  iword = iloop/32;
	  ibit = iloop%32;
	  shData = ((jtagData[iword] >> ibit )<<1) &0x2;
	  if (iloop == numBits -1) shData = shData +1;  //set the TMS high for last bit to exit Shift_IR
	  *laddr = shData;
	}
      // shift _IR tail
      *laddr = 0;  // update instruction register
      *laddr = 0;  // back to the Run_test/Idle
    }
  else if (jtagType == 4)  // JTAG data shift, start from IR-PAUSE, end at IDLE
    {
      //shift_DR header
      *laddr = 1;  //to EXIT2_IR
      *laddr = 1;  //to UPDATE_IR
      *laddr = 1;  //to SELECT-DR_SCAN
      *laddr = 0;
      *laddr = 0;
      for (iloop =0; iloop <numBits; iloop++)
	{ 
	  iword = iloop/32;
	  ibit = iloop%32;
	  shData = ((jtagData[iword] >> ibit )<<1) &0x2;
	  if (iloop == numBits -1) shData = shData +1;  //set the TMS high for last bit to exit Shift_DR
	  *laddr = shData;
	}
      // shift _DR tail
      *laddr = 1;  // update Data_Register
      *laddr = 0;  // back to the Run_test/Idle
    }
  else
    {
      printf( "\n JTAG type %d unrecognized \n",jtagType);
    }

  //  printf (" \n Emergency command executed \n");
}

void EMload(unsigned int islot,unsigned int forcenewID)
{
  unsigned long ShiftData[64], lineRead, BoardSerialNumber;
  unsigned int jtagType, jtagBit, iloop;
  FILE *svfFile;
  int byteRead, BoardType, SerialNumber;
  char bufRead[1024],bufRead2[256];
  unsigned int sndData[256];
  char *Word[16], *lastn;
  unsigned int nbits, nbytes, extrType, i, Count, nWords, nlines;
  unsigned long RegAdd;

  // Read out the board serial number first
  BoardSerialNumber = TIDSSerialNumber(islot);
  printf(" Board number from PROM usercode is: %8x \n", BoardSerialNumber);
  // Check the serial number and ask for input if necessary
  if (((BoardSerialNumber&0xfffff000) == 0x75000000) && (forcenewID != 99) )
    { BoardType = 1;}
  else if (((BoardSerialNumber&0xfffff000) == 0x7D000000) && (forcenewID != 99) )
    { BoardType = 2;}
  else if (((BoardSerialNumber&0xfffff000) == 0x71000000) && (forcenewID != 99))
    { BoardType = 3;}
  else if (((BoardSerialNumber&0xfffff000) == 0x71D50000) && (forcenewID != 99))
    { BoardType = 4;}
  else 
    { printf (" Enter the board type (1: TS;   2: TD;   3: TI;   4: TIDS):");
    scanf ("%d", &BoardType);
    printf (" Enter the board serial number: ");
    scanf("%d",&SerialNumber);

    if (BoardType == 1) 
      {BoardSerialNumber = 0x75000000 + (SerialNumber&0xfff);}
    else if (BoardType == 2) 
      {BoardSerialNumber = 0x7D000000 + (SerialNumber&0xfff);}
    else if (BoardType == 3)
      {BoardSerialNumber = 0x71000000 + (SerialNumber&0xfff);}
    else if (BoardType == 4) 
      {BoardSerialNumber = 0x71D50000 + (SerialNumber&0xfff);}
    else
      {BoardSerialNumber = 0x59480000 + (SerialNumber&0xfff);
      exit(1);}
    printf(" The board serial number will be set to: %8x \n",BoardSerialNumber);
    }

  RegAdd = ((islot<<19)&0xf80000);
  //A24 Address modifier redefined
  sysTempeSetAM(2,0x19);
  printf("\n A24 memory map is set to AM = 0x19 \n");

  //PROM JTAG reset/Idle
  Emergency(islot,0,0,ShiftData);
  printf("\n Emergency PROM JTAG reset IDLE \n");
  cpuDelay(1000000);

  //Another PROM JTAG reset/Idle
  Emergency(islot,0,0,ShiftData);
  printf("\n Emergency PROM JTAG reset IDLE \n");
  cpuDelay(1000000);

  //open the file:
  if (BoardType == 1)
    { svfFile = fopen("~jgu/ts.svf","r");}
  else if (BoardType == 2)
    { svfFile = fopen("~jgu/td.svf","r");}
  else if (BoardType == 3)
    { svfFile = fopen("~jgu/ti.svf","r");}
  else 
    { svfFile = fopen("~jgu/tids.svf","r");}
  printf("\n File is open \n");

  //initialization
  extrType = 0;
  lineRead=0;

  //  for (nlines=0; nlines<200; nlines++)
  while (fgets(bufRead,256,svfFile) != NULL)
  { 
    lineRead +=1;
    if (lineRead%1000 ==0) printf(" Lines read: %d out of 787000 \n",lineRead);
    //    fgets(bufRead,256,svfFile);
    if (((bufRead[0] == '/')&&(bufRead[1] == '/')) || (bufRead[0] == '!'))
      {
	//	printf(" comment lines: %c%c \n",bufRead[0],bufRead[1]);
      }
    else
      {
	if (strrchr(bufRead,';') ==0) 
	  {
	    do 
	      {
		lastn =strrchr(bufRead,'\n');
		if (lastn !=0) lastn[0]='\0';
		if (fgets(bufRead2,256,svfFile) != NULL)
		  {
		    strcat(bufRead,bufRead2);
		  }
		else
		  {
		    printf("\n \n  !!! End of file Reached !!! \n \n");
		    return;
		  }
	      } 
	    while (strrchr(bufRead,';') == 0);  //do while loop
	  }  //end of if
	
	// begin to parse the data bufRead
        Parse(bufRead,&Count,&(Word[0]));
	if (strcmp(Word[0],"SDR") == 0)
	  {
	    sscanf(Word[1],"%d",&nbits);
	    nbytes = (nbits-1)/8+1;
	    if (strcmp(Word[2],"TDI") == 0)
	      {
		for (i=0; i<nbytes; i++)
		  {
		    sscanf (&Word[3][2*(nbytes-i-1)+1],"%2x",&sndData[i]);
		    //  printf("Word: %c%c, data: %x \n",Word[3][2*(nbytes-i)-1],Word[3][2*(nbytes-i)],sndData[i]);
		  }
		nWords = (nbits-1)/32+1;
		for (i=0; i<nWords; i++)
		  {
		    ShiftData[i] = ((sndData[i*4+3]<<24)&0xff000000) + ((sndData[i*4+2]<<16)&0xff0000) + ((sndData[i*4+1]<<8)&0xff00) + (sndData[i*4]&0xff);
		  }

		// hijacking the PROM usercode:
		if ((nbits == 32) && (ShiftData[0] == 0x71d55948)) {ShiftData[0] = BoardSerialNumber;}

		//printf("Word[3]: %s \n",Word[3]);
		//printf("sndData: %2x %2x %2x %2x, ShiftData: %08x \n",sndData[3],sndData[2],sndData[1],sndData[0], ShiftData[0]);
		Emergency(islot,2+extrType,nbits,ShiftData);
	      }
	  }
	else if (strcmp(Word[0],"SIR") == 0)
	  {
	    sscanf(Word[1],"%d",&nbits);
	    nbytes = (nbits-1)/8+1;
	    if (strcmp(Word[2],"TDI") == 0)
	      {
		for (i=0; i<nbytes; i++)
		  {
		    sscanf (&Word[3][2*(nbytes-i)-1],"%2x",&sndData[i]);
		    //  printf("Word: %c%c, data: %x \n",Word[3][2*(nbytes-i)-1],Word[3][2*(nbytes-i)],sndData[i]);
		  }
		nWords = (nbits-1)/32+1;
		for (i=0; i<nWords; i++)
		  {
		    ShiftData[i] = ((sndData[i*4+3]<<24)&0xff000000) + ((sndData[i*4+2]<<16)&0xff0000) + ((sndData[i*4+1]<<8)&0xff00) + (sndData[i*4]&0xff);
		  }
		//printf("Word[3]: %s \n",Word[3]);
		//printf("sndData: %2x %2x %2x %2x, ShiftData: %08x \n",sndData[3],sndData[2],sndData[1],sndData[0], ShiftData[0]);
		Emergency(islot,1+extrType,nbits,ShiftData);
	      }
	  }
	else if (strcmp(Word[0],"RUNTEST") == 0)
	  {
	    sscanf(Word[1],"%d",&nbits);
	    //	    printf("RUNTEST delay: %d \n",nbits);
	    cpuDelay(nbits*45);   //delay, assuming that the CPU is at 45 MHz
	  }
	else if (strcmp(Word[0],"STATE") == 0)
	  {
	    if (strcmp(Word[1],"RESET") == 0) Emergency(islot,0,0,ShiftData);
	  }
	else if (strcmp(Word[0],"ENDIR") == 0)
	  {
	    if (strcmp(Word[1],"IDLE") ==0 )
	      {
		extrType = 0;
		printf(" ExtraType: %d \n",extrType);
	      }
	    else if (strcmp(Word[1],"IRPAUSE") ==0)
	      {
		extrType = 2;
		printf(" ExtraType: %d \n",extrType);
	      }
	    else
	      {
		printf(" Unknown ENDIR type %s\n",Word[1]);
	      }
	  }
	else
	  {
	    printf(" Command type ignored: %s \n",Word[0]);
	  }

      }  //end of if (comment statement)
  } //end of while

  //close the file
  fclose(svfFile);

  // A24 address modifier reset
  sysTempeSetAM(2,0);
  printf("\n A24 memory map is set back to its default \n");
}

void EMFPGAreload(unsigned int islot)
{
  unsigned long *laddr;
  unsigned long Dataword;
  unsigned long RegAdd;

  RegAdd = ((islot<<19)&0xf80000);
  // A24 buffer write
  sysTempeSetAM(2,0x19);

  EmergencyS(islot,0, 0, 0);  // Reset the PROM JTAG engine
  EmergencyS(islot,1, 16, 0xee); //pulse the CF pin on PROM by emergency logic;

  printf (" \n FPGA Emergency Re-Load in slot# %d ! \n", islot);
  sysTempeSetAM(2,0);  // reset the A24 AM back to its default (0x39)

}

void Parse(char *buf,int *Count,char **Word)
{
  *Word = buf;
  *Count = 0;
  while(*buf != '\0')  
    {
      while ((*buf==' ') || (*buf=='\t') || (*buf=='\n') || (*buf=='"')) *(buf++)='\0';
      if ((*buf != '\n') && (*buf != '\0'))  
	{
	  Word[(*Count)++] = buf;
	}
      while ((*buf!=' ')&&(*buf!='\0')&&(*buf!='\n')&&(*buf!='\t')&&(*buf!='"')) 
	{
	  buf++;
	}
    }
  *buf = '\0';
}

// test the firmware loading
unsigned int TItest4(unsigned int TiSlot)
{
  unsigned long ChkData1, ChkData2;
  unsigned int status;
  EMload(TiSlot,99);
  sleep(2);
  ChkData1 = FPGAusercode(TiSlot);
  ChkData2 = PROMusercode(TiSlot);
  if ( ((ChkData1 & 0xfff0f000) == 0x71001000) &&
       ((ChkData2 & 0xffffff00) == 0x71000000) )
    {printf("\n The firmware loading PASSED !! \n\n");
    status = 1;}
  else
    {printf("\n The firmware loading FAILED !! \n\n");
    status = 0;}

  return status;
}

// Test the VME trigger and data readout
unsigned int TItest5(unsigned int TiSlot)
{
  unsigned long ChkData1, ChkData2;
  unsigned int status, BytesRead;
  TImasterSet(TiSlot, 10, 100);
  sleep(2);
  TrgStart(TiSlot);
  sleep(2);
  BytesRead = tidsBERead(TiSlot);
  // Data check
  if (BytesRead == 0x90 )
    {printf("\n\n VME data generation/readout PASSED !! \n\n");
    status = 1;}
  else
    {printf("\n\n VME data generation/readout FAILED !! \n\n");
    status = 0;}

  return status;
}

// Test the front panel generic IO
unsigned int TItest6(unsigned int TiSlot)
{
  unsigned long BaseAdd, ChkData2, *laddr;
  unsigned int status, BytesRead1, BytesRead2, i;

  BaseAdd = (TiSlot<<19)&0xf80000;
  // remind to connect the special connector
  printf (" Connect the special 34-pin connector to TI... ");
  scanf("%d", status);
  TImasterSet(TiSlot, 10, 100);
  sleep(2);
  TrgStart(TiSlot);
  sysBusToLocalAdrs(0x39,BaseAdd+0x20,&laddr);
  *laddr = 0x24;
  sysBusToLocalAdrs(0x39,BaseAdd+0x28,&laddr);
  *laddr = 0;
  TrgTblLoad(TiSlot);
  sysBusToLocalAdrs(0x39,BaseAdd+0x78,&laddr);
  *laddr = 0xdd;
  sysBusToLocalAdrs(0x39,BaseAdd+0x48,&laddr);
  *laddr = 0xf;
  for (i=1; i<25; i++)
    {  sysBusToLocalAdrs(0x39,BaseAdd+0x4C,&laddr);
    *laddr = 0xf;
    cpuDelay(100000);
    *laddr = 0;
    }
  BytesRead1 = tidsBERead(TiSlot);
  BytesRead1 = tidsBERead(TiSlot);
  BytesRead2 = tidsBERead(TiSlot);
  // Data check
  if ((BytesRead1 == 0x90 ) && (BytesRead2 > 0x200))
    {printf("\n\n Front panel IO test PASSED !! \n\n");
    status = 1;}
  else
    {printf("\n\n Front panel IO test FAILED !! \n\n");
    status = 0;}

  return status;
}

// Test the fiber connections between TI boards, set A as master, then B as master
unsigned int TItest7(unsigned int TiASlot, unsigned int TiBSlot)
{
  unsigned long BaseAdd, ChkData2, *laddr;
  unsigned int status, BytesRead1, BytesRead2, i;

  BaseAdd = (TiASlot<<19)&0xf80000;
  // remind to connect the special connector
  printf (" Connect the Fiber between the two TI boards (HFBR#1)... ");
  scanf("%d", status);
  TImasterSet(TiASlot, 10, 100);
  sleep(5);
  TIsetup(TiBSlot);
  sleep(5);
  TrgStart(TiASlot);
  sleep(5);
  BytesRead1 = tidsBERead(TiASlot);
  BytesRead2 = tidsBERead(TiBSlot);
  if ( (BytesRead1 == 0x90) && (BytesRead2 == 0x90))
    {printf(" \n\n TI in slot %02x as master PASSED! \n\n", TiASlot);
    status = 1; }
  else
    {printf(" \n\n TI in slot %02x as master FAILED! \n\n", TiASlot);
    status = 0;}
  sleep(5);
  TImasterSet(TiBSlot, 10, 100);
  sleep(5);
  TIsetup(TiASlot);
  sleep(5);
  TrgStart(TiBSlot);
  sleep(5);
  BytesRead1 = tidsBERead(TiASlot);
  BytesRead2 = tidsBERead(TiBSlot);
  if ( (BytesRead1 == 0x90) && (BytesRead2 == 0x90))
    {printf(" \n\n TI in slot %02x as master PASSED!! \n\n", TiBSlot);
    status = status; }
  else
    {printf(" \n\n TI in slot %02x as master FAILED!! \n\n", TiBSlot);
    status = 0;}

  return status;
}

// test the connector IO
unsigned int TItest9(unsigned int TiSlot)
{
  unsigned long BaseAdd, *laddr;
  unsigned int status, i;
  TImasterSet(TiSlot, 10,100);
  sleep(2);
  TrgStart(TiSlot);
  sleep(2);
  printf("\n\n Check the scope ... \n\n");
  BaseAdd = (TiSlot<<19)&0xf80000;
  for (i=1; i<1000;i++)
    { 
      sysBusToLocalAdrs(0x39,BaseAdd+0x8c,&laddr);
      *laddr = 0x7000ffff;
      cpuDelay(1000000);
      sysBusToLocalAdrs(0x39,BaseAdd+0x78,&laddr);
      *laddr = 0xdd;
      cpuDelay(100000);
    }
  status = 1;
  return status;
}

// test the firmware loading, and VME readout
unsigned int TDtest4(unsigned int TdSlot)
{
  unsigned long ChkData1, ChkData2, ChkData3, BaseAdd, *laddr;
  unsigned int status;
  EMload(TdSlot,99);
  sleep(2);
  ChkData1 = FPGAusercode(TdSlot);
  ChkData2 = PROMusercode(TdSlot);

  BaseAdd = (TdSlot<<19)&0xf80000;
  sysBusToLocalAdrs(0x39,BaseAdd, &laddr);
  ChkData3 = *laddr;
  if ( ((ChkData1 & 0xfff0f000) == 0x7d001000) &&
       ((ChkData2 & 0xffffff00) == 0x7d000000) &&
       ((ChkData3 & 0xff000000) == 0x7d000000) )
    {printf("\n The firmware loading PASSED !! \n\n");
    status = 1;}
  else
    {printf("\n The firmware loading FAILED !! \n\n");
    status = 0;}

  return status;
}

// test the TD event processing (BUSY)
//Assuming that the TS is in slot21, and the SD is also in the distribution crate
// The T-frame crate is used to hold the TI boards (4 boards, connected to HFBR#1,3,6,7 or 2,4,5,8)
unsigned int TDtest6_1(unsigned int TdSlot, unsigned int TIconfig)  //TS, SD, TD setup
{
  unsigned long ChkData1, ChkData2;
  unsigned long BaseAdd, *laddr;
  unsigned int status, PayloadSlot;
  // TS setup
  TSsetup(21);
  sleep(2);
  BaseAdd = (21<<19)&0xf80000;  //TS base address
  sysBusToLocalAdrs(0x39,BaseAdd+0x100,&laddr);
  *laddr = 0x3; // SD I2C reset
  sysBusToLocalAdrs(0x39, BaseAdd+0x43c08 ,&laddr);
  if (TdSlot>12) 
    PayloadSlot = 2*(TdSlot-12);
  else 
    PayloadSlot = 2*(11-TdSlot) - 1;

  ChkData1 = (1<<(PayloadSlot-1));
  *laddr = ChkData1;
  printf(" \n SD busy set to %08x, Readback %08x \n",ChkData1, *laddr);
  TDsetupA(TdSlot, TIconfig);

  status=1;
  printf("\n TD/SD/TD setup ready! \n\n");
  return status;
}

void TDtest6_2(unsigned int TIconfig)
{
  TIsetup(3);
  cpuDelay(1000000);
  if (TIconfig > 18 || TIconfig < 11 ) 
    {
      TIsetup(4);
      cpuDelay(1000000);
      TIsetup(5);
      cpuDelay(1000000);
      TIsetup(6);
      cpuDelay(1000000);
    }
}

void TDtest6_3(void)
{
  unsigned long BaseAdd, *laddr;
  TDSstart(21);
  sleep(3);
  TIDSstart(21);
  sleep(3);

  // start VME trigger
  BaseAdd = (21<<19) &0xf80000;
  sysBusToLocalAdrs(0x39,BaseAdd+0x78, &laddr);
  *laddr = 0xdd;
  sleep(2);

  sysBusToLocalAdrs(0x39,BaseAdd+0x8c, &laddr);
  *laddr = 0x9fffffff;
  printf(" Trigger started from TS ... \n");
}

void TDtest6_x(void)
{
  unsigned long BaseAdd, *laddr;
  unsigned long TimeTi[4], BlockOld, BlockNew;
  unsigned int i, j, BytesRead[4];
  unsigned long Headera[4], Headerb[4], Headerc[4], TrgNumb[4], TrgTime[4];
  FILE *fileData;
  for (i=0; i<4; i++)
    {//BytesRead[i] = tidsBERead(i+3);
    sleep(1);

    fileData = fopen("tidsBE.dat","r");
    fscanf(fileData,"%x",&Headera[i]);
    fscanf(fileData,"%x",&Headerb[i]);
    fscanf(fileData,"%x",&Headerc[i]);
    fscanf(fileData,"%x",&TrgNumb[i]);
    fscanf(fileData,"%x",&TrgTime[i]);
    printf("\n Data readback from file \n %08x \n %08x \n %08x \n %08x \n %08x \n %08x \n",BytesRead[i], Headera[i], Headerb[i], Headerc[i], TrgNumb[i], TrgTime[i]);
    fclose(fileData);
    sleep(1);
    }
}
void TDtest6_4(unsigned int TIconfig)
{
  unsigned long BaseAdd, *laddr;
  unsigned long TimeTi[4], BlockOld, BlockNew;
  unsigned int Nti, i, j, BytesRead[4];
  unsigned long Headera[4], Headerb[4], Headerc[4], TrgNumb[4], TrgTime[4], BlockStop[4];
  FILE *fileData;
  Nti = 4;
  if (TIconfig > 10 && TIconfig < 19) Nti =1;

  for (i=0; i<Nti; i++)
    { BytesRead[i] = tidsBERead(i+3);
      sleep(1);
      fileData = fopen("tidsBE.dat","r");
      fscanf(fileData,"%x",&Headera[i]);
      fscanf(fileData,"%x",&Headerb[i]);
      fscanf(fileData,"%x",&Headerc[i]);
      fscanf(fileData,"%x",&TrgNumb[i]);
      fscanf(fileData,"%x",&TrgTime[i]);
      printf("\n Data readback from file \n %08x \n %08x \n %08x \n %08x \n %08x \n %08x \n",BytesRead[i], Headera[i], Headerb[i], Headerc[i], TrgNumb[i], TrgTime[i]);
      fclose(fileData);
      sleep(1);
    }
  // data check
  if (Nti == 4 ) 
    {
      if ( (TrgNumb[0] == TrgNumb[2]) && (TrgNumb[1] == TrgNumb[2]) && (TrgNumb[2] == TrgNumb[3]) )
	printf(" \n Event number matched, PASSED! \n");
      else 
	printf(" \n Event number did not match, FAILED! \n");

      if ( (TrgTime[0] == TrgTime[1]) && (TrgTime[1] == TrgTime[2]) && (TrgTime[2] == TrgTime[3]) )
	printf("\n Event timing match, PASSED! \n");
      else
	printf("\n Event timing did not match, FAILED! \n");
    }
  // ROC acknowledge check

  BaseAdd = (3<<19)&0xf80000;
  sysBusToLocalAdrs(0x39,BaseAdd+0x34, &laddr);
  BlockNew = (*laddr>>8) & 0xff;

  do {
    BlockOld = BlockNew;
    sleep(1);
    BlockNew = (*laddr>>8) & 0xff;
  } while (BlockNew != BlockOld);
    // Trigger stopped because of backpressure; release backpressure

  //Are they stopping at the same point?
  for (i=3; i<Nti+3; i++)
    { BaseAdd = (i<<19)&0xf80000;
      sysBusToLocalAdrs(0x39, BaseAdd+0x34, &laddr);
      BlockStop[i-3] = (*laddr >>8)&0xff;
      printf(" TI# %02x stopped at block# %02x \n", i,BlockStop[i-3]);}

  if (Nti == 4)
    {
      if ((BlockStop[0] ==BlockStop[2]) && (BlockStop[1] == BlockStop[2]) && (BlockStop[2] == BlockStop[3]))
	printf(" \n All the TI boards are stopped at block# %02x PASSED! \n",BlockStop[0]);
      else
	printf(" \n TI boards stopped asynchronously at block# %02x, %02x, %02x, %02x FAILED!\n",BlockStop[0], BlockStop[1], BlockStop[2], BlockStop[3]);
    }
    // This should not generate more triggers (should not release triggers)
  for (i=3; i<Nti+2; i++)  // loop over all the four slots
  { 
    BaseAdd = (i<<19)&0xf80000;
    sysBusToLocalAdrs(0x39,BaseAdd+0x34, &laddr);
    BlockOld = (*laddr >>8)&0xff;

    for (j=1; j< 7-i; j++)
    { 
      sysBusToLocalAdrs(0x39,BaseAdd+0x100, &laddr);
      *laddr = 0x80;
      sleep(1);
      sysBusToLocalAdrs(0x39,BaseAdd+0x34, &laddr);
      BlockNew = (*laddr >>8)&0xff;
      if (BlockNew == BlockOld) 
	printf("\n No new trigger started, PASSED! slot: %02x, j: %02x \n", i,j);
      else
	printf(" \n New trigger should not have started, FAILED! slot: %02x, j: %02x\n", i, j);
    }
  }  //end of looping over the TI boards

  for (i=2+Nti; i>2; i--)  // loop over all the four slots
  { 
    BaseAdd = (i<<19)&0xf80000;
    sysBusToLocalAdrs(0x39,BaseAdd+0x34,&laddr);
    BlockOld = (*laddr >>8) &0xff;

    for (j=0; j< 4; j++)
    { 
      sysBusToLocalAdrs(0x39,BaseAdd+0x100, &laddr);
      *laddr = 0x80;
      sleep(1);
    }
    sleep(6-Nti);
    BaseAdd = (3<<19)&0xf80000;
    sysBusToLocalAdrs(0x39,BaseAdd+0x34, &laddr);
    BlockNew = (*laddr >>8)&0xff;
    if (BlockNew == (BlockOld+5-Nti)) 
	printf("\n One more new block of trigger, PASSED! slot: %02x \n", i);
      else
	printf(" \n Missed new block of trigger, FAILED! slot: %02x \n NewBlock %03x, OldBlock %03x \n", i, BlockNew, BlockOld);
  }  //end of looping over the TI boards
}

// TIconfig =1, for HFBR#1, 3, 6, 7
// TIconfig =2, for HFBR#2, 4, 5, 8
void TDsetupA(unsigned int islotTD, unsigned int TIconfig)
{
  unsigned long *laddr;
  unsigned long Dataword;
  unsigned long RegAddTD;

  RegAddTD = ((islotTD<<19)&0xf80000);

  // FPGA reload, need ~30ms
  EMFPGAreload(islotTD);  
  cpuDelay(10000000);

  // Enable TD optic transceivers
  sysBusToLocalAdrs(0x39,RegAddTD+0x4,&laddr);	
  if (TIconfig == 1) 
    *laddr = 0x65;  // enable fiber #1, 3, 6, 7
  else if (TIconfig == 11)
    *laddr = 0x1;  // enable fiber #1
  else if (TIconfig == 12)
    *laddr = 0x2;  // enable fiber #2
  else if (TIconfig == 13)
    *laddr = 0x4;  // enable fiber #3
  else if (TIconfig == 14)
    *laddr = 0x8;  // enable fiber #4
  else if (TIconfig == 15)
    *laddr = 0x10;  // enable fiber #5
  else if (TIconfig == 16)
    *laddr = 0x20;  // enable fiber #6
  else if (TIconfig == 17)
    *laddr = 0x40;  // enable fiber #7
  else if (TIconfig == 18)
    *laddr = 0x80;  // enable fiber #8
  else
    *laddr = 0x9a; // enable fiber #2, 4, 5, 8

  cpuDelay(300000);

  // Trigger source enable set to 'VME', for the live/busy timer to work
  sysBusToLocalAdrs(0x39, RegAddTD+0x20,&laddr);
  *laddr = 0x14;  //enable the P0_trigger2 as pulsed trigger_1 from TS
  printf(" \n\n TD source setup to 0x14 in TDsetupA \n\n");
  cpuDelay(30000);

  // Enable TD Sync source input from P0
  sysBusToLocalAdrs(0x39,RegAddTD+0x24,&laddr);	
  *laddr = 0x11;  //loop back is required, or else the TD can not get the SYNC command
  cpuDelay(300000);

  // TD IOdelay reset
  sysBusToLocalAdrs(0x39,RegAddTD+0x100,&laddr);	
  *laddr = 0x4000;
  cpuDelay(3000000);

  // TD auto align the P0 sync input
  sysBusToLocalAdrs(0x39,RegAddTD+0x100,&laddr);	
  *laddr = 0x800;
  cpuDelay(3000000);

  //to add the backpressure setup later
  // Set the threshold for number of data blocks.
  sysBusToLocalAdrs(0x39,RegAddTD+0x14,&laddr);	
  *laddr = 0xa; // set the block size
  cpuDelay(300000);
  sysBusToLocalAdrs(0x39,RegAddTD+0x34,&laddr);	
  *laddr = 10;  // set the blockNumber threshold
  cpuDelay(300000);

  // Set the trigger source to P2Busy, which is BusyEn(6), enable HFBR according to the connection
  //The trigger source is set to "TRIGGER2", so disable the P2BUSY as trigger source
  sysBusToLocalAdrs(0x39,RegAddTD+0x28,&laddr);	
  if (TIconfig == 1) 
    {*laddr = 0x6500; //0x6500; // for HFBR#1, 3, 6, 7
    printf (" TD setup for HFBR# 1, 3, 6, 7. \n");}
  else if (TIconfig == 11)
    {*laddr = 0x100;  // enable fiber #1
    printf (" TD setup for HFBR# 1. \n");}
  else if (TIconfig == 12)
    {*laddr = 0x200;  // enable fiber #2
    printf (" TD setup for HFBR# 2 \n");}
  else if (TIconfig == 13)
    {*laddr = 0x400;  // enable fiber #3
    printf (" TD setup for HFBR# 3. \n");}
  else if (TIconfig == 14)
    {*laddr = 0x800;  // enable fiber #4
    printf (" TD setup for HFBR# 4. \n");}
  else if (TIconfig == 15)
    {*laddr = 0x1000;  // enable fiber #5
    printf (" TD setup for HFBR# 5. \n");}
  else if (TIconfig == 16)
    {*laddr = 0x2000;  // enable fiber #6
    printf (" TD setup for HFBR# 6. \n");}
  else if (TIconfig == 17)
    {*laddr = 0x4000;  // enable fiber #7
    printf (" TD setup for HFBR# 7. \n");}
  else if (TIconfig == 18)
    {*laddr = 0x8000;  // enable fiber #8
    printf (" TD setup for HFBR# 8. \n");}
  else  
    {*laddr = 0x9a00;  // for HFBR#2, 4, 5, 8
    printf (" TD setup for HFBR# 2, 4, 5, 8. \n");}

  cpuDelay(300000);

}

// test the firmware loading
unsigned int TStest4(unsigned int TsSlot)
{
  unsigned long ChkData1, ChkData2;
  unsigned int status;
  EMload(TsSlot,99);
  sleep(2);
  ChkData1 = FPGAusercode(TsSlot);
  ChkData2 = PROMusercode(TsSlot);
  if ( ((ChkData1 & 0xff00f000) == 0x75001000) &&
       ((ChkData2 & 0xffffff00) == 0x75000000) )
    {printf("\n The firmware loading PASSED !! \n\n");
    status = 1;}
  else
    {printf("\n The firmware loading FAILED !! \n\n");
    status = 0;}

  return status;
}

