/********************************************************************* Name: ov1720.c Created by: Pierre-A. Amaudruz / K.Olchanski implementation of the CAENCommLib functions Contents: V1720 8 ch. 12bit 250Msps for Optical link MAIN_ENABLE Build : ov1720.c, v1720.h, ov1720drv.h > gcc -g -O2 -Wall -DDO_TIMING -DMAIN_ENABLE -o ov1720.exe ov1720.c -lCAENComm -lrt Operation: > ./ov1720 -l 100 -l 0 -b 0 > ./ov1720 -l 10000 -m 100 -l 1 -b 0 $Id$ *********************************************************************/ #include #include #include #include #include "ov1720drv.h" #define LARGE_NUMBER 10000000 // Buffer organization map for number of samples uint32_t V1720_NSAMPLES_MODE[11] = { (1<<20), (1<<19), (1<<18), (1<<17), (1<<16), (1<<15) ,(1<<14), (1<<13), (1<<12), (1<<11), (1<<10)}; /*****************************************************************/ CAENComm_ErrorCode ov1720_ChannelSet(int handle, uint32_t channel, uint32_t what, uint32_t that) { uint32_t reg, mask; if (what == V1720_CHANNEL_THRESHOLD) mask = 0x0FFF; if (what == V1720_CHANNEL_OUTHRESHOLD) mask = 0x0FFF; if (what == V1720_CHANNEL_DAC) mask = 0xFFFF; reg = what | (channel << 8); return CAENComm_Write32(handle, reg, (that & 0xFFF)); } /*****************************************************************/ CAENComm_ErrorCode ov1720_ChannelGet(int handle, uint32_t channel, uint32_t what, uint32_t *data) { uint32_t reg, mask; if (what == V1720_CHANNEL_THRESHOLD) mask = 0x0FFF; if (what == V1720_CHANNEL_OUTHRESHOLD) mask = 0x0FFF; if (what == V1720_CHANNEL_DAC) mask = 0xFFFF; reg = what | (channel << 8); return CAENComm_Read32(handle, reg, data); } /*****************************************************************/ CAENComm_ErrorCode ov1720_ChannelThresholdSet(int handle, uint32_t channel, uint32_t threshold) { uint32_t reg; reg = V1720_CHANNEL_THRESHOLD | (channel << 8); printf("reg:0x%x, threshold:%x\n", reg, threshold); return CAENComm_Write32(handle, reg,(threshold & 0xFFF)); } /*****************************************************************/ CAENComm_ErrorCode ov1720_ChannelOUThresholdSet(int handle, uint32_t channel, uint32_t threshold) { uint32_t reg; reg = V1720_CHANNEL_OUTHRESHOLD | (channel << 8); printf("reg:0x%x, outhreshold:%x\n", reg, threshold); return CAENComm_Write32(handle, reg, (threshold & 0xFFF)); } /*****************************************************************/ CAENComm_ErrorCode ov1720_ChannelDACSet(int handle, uint32_t channel, uint32_t dac) { uint32_t reg, status, ncount; if ((channel >= 0) && (channel < 8)) { reg = V1720_CHANNEL_STATUS | (channel << 8); ncount = 10000; do { CAENComm_Read32(handle, reg, &status); } while ((status & 0x04) && (ncount--)); if (ncount == 0) return -1; reg = V1720_CHANNEL_DAC | (channel << 8); printf("reg:0x%x, DAC:%x\n", reg, dac); return CAENComm_Write32(handle, reg, (dac & 0xFFFF)); } return -1; } /*****************************************************************/ CAENComm_ErrorCode ov1720_ChannelDACGet(int handle, uint32_t channel, uint32_t *dac) { uint32_t reg; CAENComm_ErrorCode sCAEN = -1; if ((channel >= 0) && (channel < 8)) { reg = V1720_CHANNEL_DAC | (channel << 8); sCAEN = CAENComm_Read32(handle, reg, dac); } return sCAEN; } /*****************************************************************/ CAENComm_ErrorCode ov1720_AcqCtl(int handle, uint32_t operation) { uint32_t reg; CAENComm_ErrorCode sCAEN; sCAEN = CAENComm_Read32(handle, V1720_ACQUISITION_CONTROL, ®); // printf("sCAEN:%d ACQ Acq Control:0x%x\n", sCAEN, reg); switch (operation) { case V1720_RUN_START: sCAEN = CAENComm_Write32(handle, V1720_ACQUISITION_CONTROL, (reg | 0x4)); break; case V1720_RUN_STOP: sCAEN = CAENComm_Write32(handle, V1720_ACQUISITION_CONTROL, (reg & ~( 0x4))); break; case V1720_REGISTER_RUN_MODE: sCAEN = CAENComm_Write32(handle, V1720_ACQUISITION_CONTROL, 0x0); break; case V1720_SIN_RUN_MODE: sCAEN = CAENComm_Write32(handle, V1720_ACQUISITION_CONTROL, 0x1); break; case V1720_SIN_GATE_RUN_MODE: sCAEN = CAENComm_Write32(handle, V1720_ACQUISITION_CONTROL, 0x2); break; case V1720_MULTI_BOARD_SYNC_MODE: sCAEN = CAENComm_Write32(handle, V1720_ACQUISITION_CONTROL, 0x3); break; case V1720_COUNT_ACCEPTED_TRIGGER: sCAEN = CAENComm_Write32(handle, V1720_ACQUISITION_CONTROL, (reg & ~( 0x8))); break; case V1720_COUNT_ALL_TRIGGER: sCAEN = CAENComm_Write32(handle, V1720_ACQUISITION_CONTROL, (reg | 0x8)); break; default: printf("operation not defined\n"); break; } return sCAEN; } /*****************************************************************/ CAENComm_ErrorCode ov1720_ChannelConfig(int handle, uint32_t operation) { CAENComm_ErrorCode sCAEN; uint32_t reg, cfg; sCAEN = CAENComm_Read32(handle, V1720_CHANNEL_CONFIG, ®); sCAEN = CAENComm_Read32(handle, V1720_CHANNEL_CONFIG, &cfg); // printf("Channel_config1: 0x%x\n", cfg); switch (operation) { case V1720_TRIGGER_UNDERTH: sCAEN = CAENComm_Write32(handle, V1720_CHANNEL_CFG_BIT_SET, 0x40); break; case V1720_TRIGGER_OVERTH: sCAEN = CAENComm_Write32(handle, V1720_CHANNEL_CFG_BIT_CLR, 0x40); break; case V1720_PACK25_ENABLE: sCAEN = CAENComm_Write32(handle, V1720_CHANNEL_CONFIG, (reg | 0x800)); break; case V1720_PACK25_DISABLE: sCAEN = CAENComm_Write32(handle, V1720_CHANNEL_CONFIG, (reg & ~(0x800))); break; case V1720_NO_ZERO_SUPPRESSION: sCAEN = CAENComm_Write32(handle, V1720_CHANNEL_CONFIG, (reg & ~(0xF000))); break; case V1720_ZLE: reg &= ~(0xF000); sCAEN = CAENComm_Write32(handle, V1720_CHANNEL_CONFIG, (reg | 0x2000)); break; case V1720_ZS_AMP: reg &= ~(0xF000); sCAEN = CAENComm_Write32(handle, V1720_CHANNEL_CONFIG, (reg | 0x3000)); break; default: break; } sCAEN = CAENComm_Read32(handle, V1720_CHANNEL_CONFIG, &cfg); // printf("Channel_config2: 0x%x\n", cfg); return sCAEN; } /*****************************************************************/ CAENComm_ErrorCode ov1720_info(int handle, int *nchannels, uint32_t *data) { CAENComm_ErrorCode sCAEN; int i, chanmask; uint32_t reg; // Evaluate the event size // Number of samples per channels sCAEN = CAENComm_Read32(handle, V1720_BUFFER_ORGANIZATION, ®); *data = V1720_NSAMPLES_MODE[reg]; // times the number of active channels sCAEN = CAENComm_Read32(handle, V1720_CHANNEL_EN_MASK, ®); chanmask = 0xff & reg; *nchannels = 0; for (i=0;i<8;i++) { if (chanmask & (1<Mode 1 : @param *mvme VME structure @param base Module base address @param mode Configuration mode number @return 0: OK. -1: Bad */ CAENComm_ErrorCode ov1720_Setup(int handle, int mode) { CAENComm_ErrorCode sCAEN; switch (mode) { case 0x0: printf("--------------------------------------------\n"); printf("Setup Skip\n"); printf("--------------------------------------------\n"); case 0x1: printf("--------------------------------------------\n"); printf("Trigger from FP, 8ch, 1Ks, postTrigger 800\n"); printf("--------------------------------------------\n"); sCAEN = CAENComm_Write32(handle, V1720_BUFFER_ORGANIZATION, 0x0A); // 1K buffer sCAEN = CAENComm_Write32(handle, V1720_TRIG_SRCE_EN_MASK, 0x4000); // External Trigger sCAEN = CAENComm_Write32(handle, V1720_CHANNEL_EN_MASK, 0xFF); // 8ch enable sCAEN = CAENComm_Write32(handle, V1720_POST_TRIGGER_SETTING, 800); // PreTrigger (1K-800) sCAEN = CAENComm_Write32(handle, V1720_ACQUISITION_CONTROL, 0x00); // Reset Acq Control printf("\n"); break; case 0x2: printf("--------------------------------------------\n"); printf("Trigger from LEMO\n"); printf("--------------------------------------------\n"); sCAEN = CAENComm_Write32(handle, V1720_BUFFER_ORGANIZATION, 1); printf("\n"); break; default: printf("Unknown setup mode\n"); return -1; } return ov1720_Status(handle); } /*****************************************************************/ /*-PAA- For test purpose only */ #ifdef MAIN_ENABLE int main (int argc, char* argv[]) { /* Lock the process to an arbitrary core (#3) int mask = 0x04; if( sched_setaffinity(0, sizeof(mask), &mask) < 0 ) { printf("ERROR: affinity not set\n"); } */ CAENComm_ErrorCode sCAEN; int handle[2]; int nw, l=0, c=0, d=0, h=0, Nh; uint32_t i, lcount, data[50000], temp, lam, reg; int Nmodulo=10; int tcount=0, eloop=0; uint32_t *pdata, eStored, eSize; int loop, Nloop=10; int bshowData=0; int debug = 0; uint32_t pct=0, ct; struct timeval t1; int dt1, savelcount=0; // Added to test optivca communication (Alex 26/02/12) int testCom = 0; uint32_t regRd = 0; /* get parameters */ /* parse command line parameters */ for (i = 1; i < argc; i++) { if (argv[i][0] == '-' && argv[i][1] == 'd') debug = 1; else if (strncmp(argv[i], "-s", 2) == 0) bshowData = 1; else if (strncmp(argv[i], "-t", 2) == 0) testCom = 1; else if (argv[i][0] == '-') { if (i + 1 >= argc || argv[i + 1][0] == '-') goto usage; if (strncmp(argv[i], "-l", 2) == 0) Nloop = (atoi(argv[++i])); else if (strncmp(argv[i], "-o", 2) == 0) l = (atoi(argv[++i])); else if (strncmp(argv[i], "-b", 2) == 0) d = (atoi(argv[++i])); else if (strncmp(argv[i], "-c", 2) == 0) c = (atoi(argv[++i])); else if (strncmp(argv[i], "-m", 2) == 0) Nmodulo = (atoi(argv[++i])); else if (strncmp(argv[i], "-d", 2) == 0) d = (atoi(argv[++i])); } else { usage: printf("usage: ov1720 -l (loop count) \n"); printf(" -o link#\n"); printf(" -b board#\n"); printf(" -c interface# (PCIe)\n"); printf(" -d daisy#\n"); printf(" -m modulo display\n"); printf(" -s show data\n"); printf(" -t test communication\n\n"); return 0; } } // printf("in ov1720, l %d, d %d, c %d\n", l, d, c); #if 1 // Test board communication (Alex 26/02/12) if(testCom == 1) { // Open devices sCAEN = CAENComm_OpenDevice(CAENComm_PCIE_OpticalLink, l, d, c, &(handle[h])); if (sCAEN != CAENComm_Success) { sCAEN = CAENComm_CloseDevice(handle[h]); printf("Com Test Fail Type One\n"); return -1; } else { sCAEN = CAENComm_Read32(handle[h], V1720_BOARD_INFO, ®Rd); printf("O:%d B:%d Rev:0x%x FPGA-FW",l, d, regRd); for (i=0;i<1;i++) { reg = V1720_FPGA_FWREV | (i << 8); sCAEN = CAENComm_Read32(handle[h], reg, ®Rd); printf("/0x%x", regRd); } printf(" Com Test Success \n"); /* if((regRd & 0xffff) != 0x1003) { sCAEN = CAENComm_CloseDevice(handle[h]); printf("Com Test Fail Type Two\n"); return -1; } */ } sCAEN = CAENComm_CloseDevice(handle[h]); return 0; } // // Open devices sCAEN = CAENComm_OpenDevice(CAENComm_PCIE_OpticalLink, l, d, c, &(handle[h])); if (sCAEN != CAENComm_Success) { handle[h] = -1; printf("1st CAENComm_OpenDevice [l:%d, d:%d]: Error %d\n", l, d, sCAEN); } else { printf("1st Device found : Interface:%d Link:%d Daisy:%d Handle[%d]:%d\n", c, l, d, h, handle[h]); sCAEN = ov1720_Status(handle[h]); h++; } Nh = h; printf("Handles opened (%d)\n", Nh); CAENComm_CloseDevice(handle[0]); printf("Init Handles released\n"); // // Open devices h = 0; sCAEN = CAENComm_OpenDevice(CAENComm_PCIE_OpticalLink, l, d, c, &(handle[h])); if (sCAEN != CAENComm_Success) { handle[h] = -1; printf("2nd CAENComm_OpenDevice [l:%d, d:%d]: Error %d\n", l, d, sCAEN); } else { printf("2nd Device found : Interface:%d Link:%d Daisy:%d Handle[%d]:%d\n", c, l, d, h, handle[h]); sCAEN = ov1720_Status(handle[h]); h++; } Nh = h; //sCAEN = ov1720_AcqCtl(handle[0], V1720_RUN_STOP); //sCAEN = CAENComm_Write32(handle[0], V1720_SW_CLEAR, 0); sCAEN = CAENComm_Write32(handle[0], V1720_SW_RESET, 0); printf("Init After stop\n"); #endif #if 0 // // Open devices for (h=0, l=0;l<1;l++) { for (d=0;d<2;d++) { // Open VME interface sCAEN = CAENComm_OpenDevice(CAENComm_PCIE_OpticalLink, l, d, c, &(handle[h])); if (sCAEN != CAENComm_Success) { handle[h] = -1; printf("CAENComm_OpenDevice [l:%d, d:%d]: Error %d\n", l, d, sCAEN); } else { printf("Device found : Link:%d Daisy:%d Handle[%d]:%d\n", l, d, h, handle[h]); sCAEN = ov1720_Status(handle[h]); h++; } } } Nh = h; printf("Handles opened (%d)\n", Nh); #endif #if 1 for (h=0;h