vt48.c

Go to the documentation of this file.
00001 /*********************************************************************
00002   @file
00003   Name:         vt48.c
00004   Created by:   Pierre-Andre Amaudruz, Chris Ohlmann
00005 
00006   Contents:      Routines for accessing the VT48 Triumf board
00007 
00008 gcc -g -O2 -Wall -g -DMAIN_ENABLE -I/home1/midas/midas/include 
00009     -o vt48 vt48.c vmicvme.o -lm -lz -lutil -lnsl -lpthread -L/lib
00010     -lvme  
00011   
00012 $Id: vt48.c 3753 2007-07-16 22:20:28Z amaudruz $
00013 *********************************************************************/
00014 #include <stdio.h>
00015 #include <string.h>
00016 #include <stdlib.h>
00017 #include "vt48.h"
00018 
00019 /********************************************************************/
00020 /**
00021 Read one Event
00022 @param myvme vme structure
00023 @param base  TF48 base address
00024 @param pdest Destination pointer
00025 @param entry return number of entry
00026 @return void
00027 */
00028 int vt48_EventRead(MVME_INTERFACE *myvme, DWORD base, DWORD *pdest, int *nentry)
00029 {
00030   int cmode, timeout, i, nwords, bfull, bempty;
00031   DWORD hdata = 0;
00032     
00033   mvme_get_dmode(myvme, &cmode);
00034   mvme_set_dmode(myvme, MVME_DMODE_D32);
00035 
00036   /*
00037   *nentry = mvme_read_value(myvme, base+VT48_OCCUPANCY_RO);
00038   printf ("nentry:%x\n", *nentry);
00039 
00040   *nentry &= 0xFFF;
00041   for (i=0 ; i<*nentry ; i++) {
00042     pdest[i] = mvme_read_value(myvme, base+VT48_DATA_FIFO);
00043   }
00044   */
00045 
00046   /*
00047   nwords = mvme_read_value(myvme, base+VT48_OCCUPANCY_RO);
00048   bempty = nwords & 0x4000;
00049   bfull = nwords & 0x8000;
00050   nwords &= 0xFFF;  
00051   */
00052   
00053   *nentry = 0;
00054   
00055   timeout=300;  
00056   do {
00057     timeout--;
00058     if (!(mvme_read_value(myvme, base+VT48_OCCUPANCY_RO) & 0x4000)) {   // Buffer Not Empty
00059       hdata = mvme_read_value(myvme, base+VT48_DATA_FIFO);
00060     }
00061   } while (!((hdata & 0xF0000000) == VT48_HEADER) && (timeout)); 
00062     
00063   if (timeout == 0) {
00064     *nentry = 0;
00065     //printf("timeout on header  data:0x%lx\n", hdata);
00066     mvme_set_dmode(myvme, cmode);
00067     return VT48_ERR_NODATA;
00068   }
00069 
00070   pdest[*nentry] = hdata;
00071   *nentry += 1;
00072   timeout=2000;
00073   do {
00074     timeout--;
00075     if (!(mvme_read_value(myvme, base+VT48_OCCUPANCY_RO) & 0x4000)) {   // Buffer Not Empty
00076       pdest[*nentry] = mvme_read_value(myvme, base+VT48_DATA_FIFO);
00077       *nentry += 1;
00078       timeout=2000;
00079     }
00080   } while (!((pdest[*nentry-1] & 0xF0000000) == VT48_TRAILER) && timeout); 
00081 
00082   if (timeout == 0) {
00083     printf("timeout on Trailer  data:0x%x\n", pdest[*nentry-1]);
00084     printf("nentry:%d data:0x%x base:0x%x \n", *nentry, pdest[*nentry], base+VT48_DATA_FIFO);
00085   }
00086   *nentry--;
00087     
00088   mvme_set_dmode(myvme, cmode);
00089   return (VT48_SUCCESS);
00090 }
00091 
00092 /*****************************************************************/
00093 /**
00094  */
00095 void vt48_RegWrite(MVME_INTERFACE *mvme, DWORD base, DWORD reg, DWORD data)
00096 {
00097   int cmode;
00098 
00099   mvme_get_dmode(mvme, &cmode);
00100   mvme_set_dmode(mvme, MVME_DMODE_D32);
00101   mvme_write_value(mvme, base+reg, data);
00102   mvme_set_dmode(mvme, cmode);
00103   return;
00104 }
00105 
00106 /**
00107  */
00108 void vt48_WindowSet(MVME_INTERFACE *mvme, DWORD base, float window)
00109 {
00110   int cmode;
00111 
00112   mvme_get_dmode(mvme, &cmode);
00113   mvme_set_dmode(mvme, MVME_DMODE_D32);
00114   printf("Window() Not implemented yet\n");
00115   mvme_set_dmode(mvme, cmode);
00116   return;
00117 }
00118 
00119 /**
00120  */
00121 void vt48_WindowOffsetSet(MVME_INTERFACE *mvme, DWORD base, float offset)
00122 {
00123   int cmode;
00124 
00125   mvme_get_dmode(mvme, &cmode);
00126   mvme_set_dmode(mvme, MVME_DMODE_D32);
00127   printf("WindowOffset() Not implemented yet\n");
00128   mvme_set_dmode(mvme, cmode);
00129   return;
00130 }
00131 
00132 /*****************************************************************/
00133 /**
00134  */
00135 DWORD vt48_RegRead(MVME_INTERFACE *mvme, DWORD base, WORD reg)
00136 {
00137   int cmode;
00138   DWORD value;
00139 
00140   mvme_get_dmode(mvme, &cmode);
00141   mvme_set_dmode(mvme, MVME_DMODE_D32);
00142   value = mvme_read_value(mvme, base+reg);
00143   mvme_set_dmode(mvme, cmode);
00144   return value;
00145 }
00146 
00147 /*****************************************************************/
00148 /**
00149  */
00150 void vt48_RegPrint(MVME_INTERFACE *mvme, DWORD base)
00151 {
00152   int cmode, i, j;
00153   DWORD val1;
00154 
00155   mvme_get_dmode(mvme, &cmode);
00156   mvme_set_dmode(mvme, MVME_DMODE_D32);
00157   printf("vt48 Register\n");
00158   vt48_RegWrite(mvme, base, VT48_CMD_REG, VT48_AMT_CFG_RW);
00159   usleep(10000);
00160   
00161   for (i=0, j=0;i<15;i++,j+=4) {
00162     val1 = vt48_RegRead(mvme, base, VT48_CSR0_REG+j);
00163     printf("AMT Register CSR%2.2d: 0x%x \n", i, val1);
00164   }
00165   mvme_set_dmode(mvme, cmode);
00166 }
00167 
00168 /*****************************************************************/
00169 /**
00170 Sets all the necessary paramters for a given configuration.
00171 The configuration is provided by the mode argument.
00172 Add your own configuration in the case statement. Let me know
00173 your setting if you want to include it in the distribution.
00174 @param *mvme VME structure
00175 @param  base Module base address
00176 @param mode  Configuration mode number
00177 @param *nentry number of entries requested and returned.
00178 @return MVME_SUCCESS
00179 */
00180 int  vt48_Setup(MVME_INTERFACE *mvme, DWORD base, int mode)
00181 {
00182   int  cmode;
00183 
00184   mvme_get_dmode(mvme, &cmode);
00185   mvme_set_dmode(mvme, MVME_DMODE_D32);
00186 
00187   switch (mode) {
00188   case 0x1:
00189     printf("Default setting after power up (mode:%d)\n", mode);
00190     printf("Same configuration in both AMTs... Ch0-47 enabled\n");
00191     printf("Time relative to trigger, Trigger matching enabled\n");
00192 
00193     vt48_RegWrite(mvme, base, VT48_CMD_REG, 0x10);  // AMT Global Reset
00194 
00195     vt48_RegWrite(mvme, base, VT48_CSR0_REG, 0xf0200020); // enable direct (Trigger/Reset)
00196     vt48_RegWrite(mvme, base, VT48_CSR1_REG, 0x0000);     // mask window
00197     vt48_RegWrite(mvme, base, VT48_CSR2_REG, 0x0080);     // search window (# of 20ns clock)
00198     vt48_RegWrite(mvme, base, VT48_CSR3_REG, 0x0070);     // match window ( same)
00199     vt48_RegWrite(mvme, base, VT48_CSR4_REG, 0x0f80);     // reject offset (same) 
00200     vt48_RegWrite(mvme, base, VT48_CSR5_REG, 0x0000);     // event offset (same)
00201     vt48_RegWrite(mvme, base, VT48_CSR6_REG, 0x0fa0);     // bunch offset (same)
00202     vt48_RegWrite(mvme, base, VT48_CSR7_REG, 0x0000);     // coarse time offset (same)
00203     vt48_RegWrite(mvme, base, VT48_CSR8_REG, 0x0fff);     // counter roll over (same)
00204     vt48_RegWrite(mvme, base, VT48_CSR9_REG, 0xf3000301); // TDCs Id 0,1... (should remain fixed)
00205     vt48_RegWrite(mvme, base, VT48_CSR10_REG, 0x0af1);    // Different mask enable (trig match, relative)
00206     //vt48_RegWrite(mvme, base, VT48_CSR10_REG, 0x0871);  //                       (disable trigger match)
00207     //vt48_RegWrite(mvme, base, VT48_CSR10_REG, 0x0a71);  //                        disable relative)
00208     vt48_RegWrite(mvme, base, VT48_CSR11_REG, 0x0e11);    // More mask enable (overflows ... see man)
00209     vt48_RegWrite(mvme, base, VT48_CSR12_REG, 0x01ff);    // Enable Error report
00210     vt48_RegWrite(mvme, base, VT48_CSR13_REG, 0x0fff);    // Channel 0..11 enable (TDC1 all on, TDC2 - all on)
00211     vt48_RegWrite(mvme, base, VT48_CSR14_REG, 0x0fff);    // Channel 12..23 enable (TDC1 all on, TDC2 - all on)
00212 
00213     break;
00214 
00215   case 0x2:
00216     printf("Default setting after power up (mode:%d)\n", mode);
00217     printf("Same configuration in both AMTs... Ch0-23 (TDC ID=1), Ch24-47 (disable)\n");
00218 
00219     vt48_RegWrite(mvme, base, VT48_CMD_REG, 0x10);  // AMT Global Reset
00220 
00221     vt48_RegWrite(mvme, base, VT48_CSR0_REG, 0xf0200020); // enable direct (Trigger/Reset)
00222     vt48_RegWrite(mvme, base, VT48_CSR1_REG, 0x0000);     // mask window
00223     vt48_RegWrite(mvme, base, VT48_CSR2_REG, 0x0080);     // search window (# of 20ns clock)
00224     vt48_RegWrite(mvme, base, VT48_CSR3_REG, 0x0070);     // match window ( same)
00225     vt48_RegWrite(mvme, base, VT48_CSR4_REG, 0x0f80);     // reject offset (same) 
00226     vt48_RegWrite(mvme, base, VT48_CSR5_REG, 0x0000);     // event offset (same)
00227     vt48_RegWrite(mvme, base, VT48_CSR6_REG, 0x0fa0);     // bunch offset (same)
00228     vt48_RegWrite(mvme, base, VT48_CSR7_REG, 0x0000);     // coarse time offset (same)
00229     vt48_RegWrite(mvme, base, VT48_CSR8_REG, 0x0fff);     // counter roll over (same)
00230     vt48_RegWrite(mvme, base, VT48_CSR9_REG, 0xf3020301); // TDCs id ... (should remain fixed)
00231     vt48_RegWrite(mvme, base, VT48_CSR10_REG, 0x0af1);    // Different mask enable (trig match, relative)
00232     //vt48_RegWrite(mvme, base, VT48_CSR10_REG, 0x0871);  //                       (disable trigger match)
00233     //vt48_RegWrite(mvme, base, VT48_CSR10_REG, 0x0a71);  //                        disable relative)
00234     vt48_RegWrite(mvme, base, VT48_CSR11_REG, 0x0e11);    // More mask enable (overflows ... see man)
00235     vt48_RegWrite(mvme, base, VT48_CSR12_REG, 0x01ff);    // Enable Error report
00236     vt48_RegWrite(mvme, base, VT48_CSR13_REG, 0xf0000fff);// Channel 0..11 enable (TDC1 all on, TDC2 - all off)
00237     vt48_RegWrite(mvme, base, VT48_CSR14_REG, 0xf0000fff);// Channel 12..23 enable (TDC1 all on, TDC2 - all off)
00238 
00239     break;
00240 
00241   case 0x3:
00242     printf("Modified setting (mode:%d)\n", mode);
00243     printf("... nothing for now\n");
00244 
00245     break;
00246   case 0x11:
00247     printf("Modified setting (mode:%d)\n", mode);
00248     printf("... TRIGGER SENT!!\n");
00249     vt48_RegWrite(mvme, base, VT48_CMD_REG, 0xf);
00250     break;
00251   default:
00252     printf("Unknown setup mode\n");
00253     mvme_set_dmode(mvme, cmode);
00254     return -1;
00255   }
00256 
00257   // Configure AMTs
00258   vt48_RegWrite(mvme, base, VT48_CMD_REG, VT48_AMT_CFG_RW); // Write to the AMT 
00259   usleep(200);
00260   vt48_RegWrite(mvme, base, VT48_CMD_REG, VT48_AMT_CFG_RW); // Force update of Read-back Reg (CSR0..14) 
00261   usleep(200);
00262   
00263   // AMT Bunch Reset
00264   vt48_RegWrite(mvme, base, VT48_CMD_REG, 0x12);
00265   usleep(1);
00266   
00267   //  vt48_Status(mvme, base);
00268   mvme_set_dmode(mvme, cmode);
00269   return 0;
00270 }
00271 
00272 /*****************************************************************/
00273 void  vt48_Status(MVME_INTERFACE *mvme, DWORD base)
00274 {
00275   int cmode, i;
00276   DWORD val1, val2;
00277 
00278   mvme_get_dmode(mvme, &cmode);
00279   mvme_set_dmode(mvme, MVME_DMODE_D32);
00280   printf("----- VT48 Status -- Base:0x%x -----\n", base);
00281   val1 = vt48_RegRead(mvme, base, VT48_CSR_RO);
00282   printf("CSR (Occupancy) : 0x%x\n", val1);
00283   vt48_RegWrite(mvme, base, VT48_CMD_REG, VT48_AMT_ID_R);
00284   usleep(100000);
00285   val1 = vt48_RegRead(mvme, base, VT48_ID1_REG_RO);
00286   val2 = vt48_RegRead(mvme, base, VT48_ID2_REG_RO);
00287   printf("AMTs ID         : 0x%x  - 0x%x\n", val1, val2);
00288   vt48_RegWrite(mvme, base, VT48_CMD_REG, VT48_AMT_STATUS_R);
00289   usleep(100000);
00290 
00291   // Read AMT3 Status Reg
00292   for (i=0;i<6;i++) {
00293     val1 = vt48_RegRead(mvme, base, VT48_CSR16_REG+i*4);
00294     printf("AMT3 CSR%2d     : 0x%8.8x\n", 16+i, val1);
00295   }
00296 
00297   // Read Control Registers
00298   for (i=0;i<15;i++) {
00299     val1 = vt48_RegRead(mvme, base, VT48_CSR0_REG+i*4);
00300     printf("AMT3 CTL%2d     : 0x%8.8x\n", i, val1);
00301   }
00302 
00303   // Read Read-back Reg from last configuration
00304   for (i=0;i<15;i++) {
00305     val1 = vt48_RegRead(mvme, base, VT48_CSR0_RB_REG+i*4);
00306     printf("AMT3 CSR-RB%2d  : 0x%8.8x\n", i, val1);
00307   }
00308   mvme_set_dmode(mvme, cmode);
00309 }
00310 
00311 /*****************************************************************/
00312 /*-PAA- For test purpose only */
00313 #ifdef MAIN_ENABLE
00314 int main (int argc, char* argv[]) {
00315   int i;
00316   DWORD VT48_BASE  = 0x300000;
00317   MVME_INTERFACE *myvme;
00318 
00319   int status, mode;
00320   WORD reg;
00321   DWORD value;
00322 
00323 
00324   if ((argc == 2) && (strncmp(argv[1],"-h",2))==0) {
00325 
00326     printf("vt48 interactive:\n");
00327     printf("                   -h : help\n");
00328     printf("                  <mode> : 0:status, 1..9: setup, 77,78:test\n");
00329     printf("                  w <reg> <value>: Write all in hex\n");
00330     printf("                  r <reg>        : Read in hex\n");
00331   }
00332     
00333 
00334   // Test under vmic
00335   status = mvme_open(&myvme, 0);
00336 
00337   // Set am to A24 non-privileged Data
00338   mvme_set_am(myvme, MVME_AM_A24_ND);
00339 
00340   // Set dmode to D32
00341   mvme_set_dmode(myvme, MVME_DMODE_D32);
00342 
00343   /* parse command line parameters */
00344   switch (argc-1) {
00345   case 0:   // no args
00346     vt48_RegPrint(myvme, VT48_BASE);
00347     vt48_Setup(myvme, VT48_BASE, 1);
00348     vt48_RegPrint(myvme, VT48_BASE);
00349     break;
00350   case 1:   // 1 arg mode
00351     mode = atoi(argv[1]);
00352     switch (mode) {
00353     case 0:
00354       vt48_Status(myvme, VT48_BASE);
00355       break;
00356     case 77:
00357       vt48_RegWrite(myvme, VT48_BASE, VT48_CSR0_REG, 0xabcdef);
00358       while (1) {
00359         // vt48_RegWrite(myvme, VT48_BASE, VT48_CSR0_REG, 0xabcdef);
00360         i = vt48_RegRead(myvme, VT48_BASE, VT48_CSR0_REG);
00361         //    printf("0x%x\n", i);
00362         // usleep(1);
00363       }
00364       break;
00365     case 78:
00366       vt48_RegWrite(myvme, VT48_BASE, 0x1000, 0xabcdef);
00367       while (1) {
00368         // vt48_RegWrite(myvme, VT48_BASE, 0x1000, 0xabcdef);
00369         i = vt48_RegRead(myvme, VT48_BASE, 0x1000);
00370         //    printf("0x%x\n", i);
00371         // usleep(1);
00372       }
00373       break;
00374     default:
00375       vt48_Setup(myvme, VT48_BASE, mode);
00376       break;
00377     }
00378     break;
00379   case 2:   // 2 arg read 
00380     if ((argc == 3) && (strncmp(argv[1],"r",2))==0) {
00381       reg = strtoul(argv[2], NULL, 16);
00382       // Configure AMTs
00383       vt48_RegWrite(myvme, VT48_BASE, VT48_CMD_REG, VT48_AMT_CFG_RW);
00384       value = vt48_RegRead(myvme, VT48_BASE, reg*4 + VT48_CSR0_REG);
00385       printf("Read  : reg:0x%x  ->  val:0x%x\n", reg, value);
00386     }
00387     break;
00388   case 3:   // 3 arg write 
00389     if ((argc == 4) && (strncmp(argv[1],"w",2))==0) {
00390       reg = strtoul(argv[2], NULL, 16);
00391       value = strtoul(argv[3], NULL, 16);
00392       printf("Write : reg:0x%x  <-  val:0x%x\n", reg, value);
00393       vt48_RegWrite(myvme, VT48_BASE, reg, value);
00394       // Configure AMTs
00395       vt48_RegWrite(myvme, VT48_BASE, VT48_CMD_REG, VT48_AMT_CFG_RW);
00396     }
00397     break;
00398   }
00399   status = mvme_close(myvme);
00400   
00401   return 1;
00402 }
00403 #endif
00404 
00405 /* emacs
00406  * Local Variables:
00407  * mode:C
00408  * mode:font-lock
00409  * tab-width: 8
00410  * c-basic-offset: 2
00411  * End:
00412  */

Midas DOC Version 2.0.2 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Sergio Ballestrero - Suzannah Daviel - Doxygen - Peter Green - Qing Gu - Greg Hackman - Gertjan Hofman - Paul Knowles - Exaos Lee - Rudi Meier - Glenn Moloney - Dave Morris - John M O'Donnell - Konstantin Olchanski - Renee Poutissou - Tamsen Schurman - Andreas Suter - Jan M.Wouters - Piotr Adam Zolnierczuk