#include #include #include "CAENVMElib.h" #include "Panel_principal.h" #include "tdcV767.h" #include #include #define NUMERO_MODULOS_DATOS 3 #define V767_NUM_CANALES 128 #define V767_REG_HANDSHAKE 0x50 #define V767_REG_MICROPROG 0x52 #define V767_READ_ENABLE_PATTERN 0x2600 #define V767_READ_WINDOW_WIDTH 0x3100 #define V767_READ_WINDOW_OFFSET 0x3300 #define V767_ENABLE_CHANNEL 0x2000 #define V767_DISABLE_CHANNEL 0x2100 void funcion_bucle(void); int salir=0; // Variables globales // Variables del VME. El 1 indice señala la ranura del VME, de 1 a 21, el valor 0 // no corresponde a ninguna ranura. int base[22]; /* El vector base contiene las direciones base de las tarjetas que están en las 21 ranuras. Una dirección nula se corresponde con una ranura vacía.*/ char modulo[22][10]; /* Este vector contiene los nombres de los módulos insertados en las ranuras.*/ int dato1[22]; /* Se guarda un dato entero por cada ranura. En el caso de los discriminadores los bits de este dato definen los canales activos.*/ int dato2[22]; /* Se guarda un dato entero por cada ranura. En el caso de los discriminadores este dato se corresponde con la anchura del pulso de salida.*/ int niv_disc[22][16]; /* Se guardan los niveles de discriminacion, 16 canales por tarjeta El indice 0 no corresponde a ninguna ranura*/ int toma_datos[22]; /* Este dato indica al sistema si cada uno de los modulos de VME participan en la toma de datos (Valor no nulo) o no (Valor nulo). Si participa en la toma de datos, el valor indica que tipo de modulo es, adc (V785) o tdc (V1190B).*/ int indice[22]; /* Cada ranura con un adc o tdc tiene una entrada de una estructura de datos de configuración. Este indice es el asignado a cada ranura. Si la ranura no está asignada, el índice vale -1,*/ // Registros de configuración de los modulos de toma de datos. struct _config { int ranura; int tipo; // Tipo de modulo,adc o tdc int num_reg; // Numero de registros de datos activos int indice_reg_viejo; // Indice del registro mas antiguo int indice_reg_nuevo; // Indice del registro mas reciente char label[V767_NUM_CANALES][50]; // Nombre de los canales int code[V767_NUM_CANALES]; // código de canal (0-1F). }config[NUMERO_MODULOS_DATOS]; long BHandle; int file_handle; int handPanel_principal,handPanelV767; main() { CVBoardTypes VMEBoard; short Link; short Device; int a1,a2,a3,a4,addr,com,data,tot,contador,ranura,datow; int indice_modulo_datos; char c1[50],c2[50],linea[200]; handPanel_principal=LoadPanel (0, "Panel_principal.uir", PANELPR); // Inicializacion del controlador del VME VMEBoard = cvV2718;//Declaración de la tarjeta de control del VME Link=0; Device=0; ranura=(-1); /* if(CAENVME_Init(VMEBoard, Device, Link, &BHandle) != cvSuccess ) { printf("\n\nCAENVME_Init Error opening the device\n"); exit(1); } CAENVME_SystemReset(BHandle); */ // Inicializacion de laa tarjetas del VME for(a1=0;a1<5;a1++) //Inicializa todas las ranuras del VME como vacias { base[a1]=0; // Un vector base nulo indica una ranura vacía toma_datos[a1]=0; indice[a1]=(-1); Fmt(modulo[a1],"-"); } // Abre el fichero de inicialización file_handle=OpenFile ("Mapa_VME_muon.txt", VAL_READ_ONLY, 0, VAL_ASCII); indice_modulo_datos=0; while(1) // Longitud indefinida del fichero de inicialización { // Lee una linea del fichero de mapeo if(ScanFile (file_handle, "%l>%s[t-w190]", linea)<=0) break;//Termina cuando no hay lineas // Linea de definicion de ranura. if(linea[0]=='*') { Scan(linea,"%s%i%s%i[r16]",c1,&ranura,c2,&a1);//Lee la dirección base de la ranura Fmt(modulo[ranura],"%s",c2); base[ranura]=a1; // Todos los modulos adc o tdc participan en la toma de datos. // c2 contiene la identificación del módulo indice[ranura]=indice_modulo_datos; config[indice_modulo_datos].ranura=ranura; config[indice_modulo_datos].tipo=toma_datos[ranura]; indice_modulo_datos++; Fmt(c2,"%s<%x",a1); ReplaceListItem (handPanel_principal, PANELPR_LISTBOX, (ranura-1), c2, 0); } // Linea de inicializacion.. else if(linea[0]=='-' || linea[0]=='m' || linea[0]=='w' || linea[0]=='r' ) { if(ranura==(-1)) // Error, Antes de inicializar se necesita haber identificado una ranuara { FmtOut("Error, linea de inicio sin linea previa de ranura\n"); exit(-1); } if(linea[0]=='-')// Linea que empieza por -, escribe un dato en una dirección { Scan(linea,"%s%i[r16]%i[r16]%s",c1,&a1,&data,c2);// Lee la dirección del registro (a1) y el dato. addr= base[ranura]+a1; // CAENVME_WriteCycle(BHandle,addr,&data,cvA32_U_DATA,cvD16); //Escribe el dato o comando. } else { // Lee la dirección donde escribir el comando (a1), la dirección del handshake (a2) // y el comando a escribir (com) Scan(linea,"%s%i[r16]%i[r16]%i[r16]%s",c1,&a1,&a2,&com,c2); addr= base[ranura]+a2; /* while(1) { CAENVME_ReadCycle(BHandle,addr,&a3,cvA32_U_DATA,cvD16); if((a3&3)==1)break; // Comprueba que tiene permiso de escritura (WRITE_OK activo) } */ addr= base[ranura]+a1; com=com<<8; // CAENVME_WriteCycle(BHandle,addr,&com,cvA32_U_DATA,cvD16); //Escribe comando. if(linea[0]=='w') //Escribe un comando de escritura de datos del microprograma { addr= base[ranura]+a2; /* while(1) { CAENVME_ReadCycle(BHandle,addr,&a3,cvA32_U_DATA,cvD16); if((a3&3)==1)break; // Comprueba que tiene permiso de escritura (WRITE_OK activo) } addr= base[ranura]+a1; CAENVME_WriteCycle(BHandle,addr,&datow,cvA32_U_DATA,cvD16); //Escribe el dato. */ } else if(linea[0]=='r') //Ejecuta un comando microprogramado de lectura { if(com==(0x16<<8)) { FmtOut("No hay lecturas programadas\n"); } } } } else continue; // Cualquier otro tipo de linea lo considera un comentario } CloseFile (file_handle); // Inicializacion del mapeo de los electrodos de la cámara a canales de tarjetas del VME /* Este mapeo se carga del fichero "Mapa_Camara.txt". En él, las lineas que comienzan con el caracter '/' son consideradas comentarios. El formato del resto de las lineas es el siguiente: Modulo TDC asociado, 0 ó 1. Canal de TDC, 0 a 127. Indicador alfanumérico del hilo: XY_Z_C, donde: X indica la orientación de la cámara, A ó B (0 ó 1). Y indica la posición en altura de la cámara, U ó D (0 ó 1). Z indica el número de capa, de 0 a 3. C indica el canal de la capa, de 0 a 15. Número codificado del hilo, es igual a X*10000+Y*1000+Z*100+C */ file_handle=OpenFile ("Mapa_Camara_muon.txt", VAL_READ_ONLY, 0, VAL_ASCII); while(1) // Longitud indefinida del fichero de mapeo { if(ScanFile (file_handle, "%l>%s[t-w190]", linea)<=0) break;// Lee una linea del fichero de mapeo if(linea[0]=='/')continue; // Linea de comentario. if(linea[0]=='q')break; // Linea de finalizacion. Scan(linea,"%i%i%s%i",&a1,&a2,c1,&a3);//Lee los datos del mapeo Fmt(config[a1].label[a2],"%s<%s",c1); config[a1].code[a2]=a3; } CloseFile (file_handle); DisplayPanel (handPanel_principal); RunUserInterface (); } /*=========================================================================*/ /* Rutinas de lectura/escritura en el registro de comandos del V767 ============================================================================*/ EscribeRegistroMicro(int addr,int dato) { int a1,a3,a4; a1= addr+V767_REG_HANDSHAKE; /* while(1) { CAENVME_ReadCycle(BHandle,a1,&a3,cvA32_U_DATA,cvD16); if((a3&3)==1)break; // Comprueba que tiene permiso de escritura (WRITE_OK activo) } */ Delay(0.01); a1= addr+V767_REG_MICROPROG; a4=dato; // CAENVME_WriteCycle(BHandle,a1,&a4,cvA32_U_DATA,cvD16); //Escribe comando. return(0); } LeeRegistroMicro(int addr,int* dato) { int a1,a3,a4; a1= addr+V767_REG_HANDSHAKE; /* while(1) { CAENVME_ReadCycle(BHandle,a1,&a3,cvA32_U_DATA,cvD16); if((a3&3)==1)break; // Comprueba que tiene permiso de lectura (READ_OK activo) } */ Delay(0.01); a1= addr+V767_REG_MICROPROG; // CAENVME_ReadCycle(BHandle,a1,&dato,cvA32_U_DATA,cvD16); return(0); } /*====================================================================== Rutinas comunes de todos los paneles ========================================================================*/ /*---------------------------------------------------------------------------------- Salida de los paneles, excepto el principal. */ int CVICALLBACK QuitCallBack (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: RemovePopup (0);// Elimina el panel break; } return 0; } /*====================================================================== LLamadas de control del Panel principal. ======================================================================== Control del switch R/W. */ int CVICALLBACK SetRWCallBack (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { int a1; switch (event) { case EVENT_COMMIT: GetCtrlVal (handPanel_principal, PANELPR_BINARYSWITCH, &a1); if(a1)SetCtrlAttribute (handPanel_principal, PANELPR_NUMERIC_2, ATTR_CTRL_MODE , VAL_INDICATOR); else SetCtrlAttribute (handPanel_principal, PANELPR_NUMERIC_2, ATTR_CTRL_MODE , VAL_NORMAL); break; } return 0; } /*-------------------------------------------------------------------------- Salida del programa */ int CVICALLBACK SalirCallBack (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: salir=1; // CAENVME_End(BHandle); QuitUserInterface (0); break; } return 0; } /*--------------------------------------------------------------------------- Ejecuta un R/W al VME */ int CVICALLBACK VME_RWCallBack (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { int a1,a2,offset,addr,dato,address_modif; switch (event) { case EVENT_COMMIT : GetCtrlIndex (handPanel_principal, PANELPR_RINGSLIDE, &a1); if(base[a1]==0)break; GetCtrlVal (handPanel_principal, PANELPR_BINARYSWITCH, &a2); GetCtrlVal (handPanel_principal, PANELPR_NUMERIC, &offset); addr=base[a1]+offset; if(base[a1]<0x1000000)address_modif=cvA24_U_DATA; else address_modif=cvA32_U_DATA; if(a2) { // CAENVME_ReadCycle(BHandle,addr,&dato,address_modif,cvD16); SetCtrlVal (handPanel_principal, PANELPR_NUMERIC_2, dato); } else { GetCtrlVal (handPanel_principal, PANELPR_NUMERIC_2, &dato); // CAENVME_WriteCycle(BHandle,addr,&dato,address_modif,cvD16); } break; } return 0; } /*-------------------------------------------------------------------------------- Llama a los paneles de control de los tdc V767 */ int CVICALLBACK VMEPanelCallBack (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { int a1; switch (event) { case EVENT_COMMIT: GetCtrlIndex (handPanel_principal, PANELPR_RINGSLIDE, &a1); // FmtOut("%i base %x\n",a1,base[a1+1]); if((unsigned int)base[a1+1]<0x1000000)break; handPanelV767=LoadPanel (handPanel_principal, "tdcV767.uir", PANV767); InstallPopup (handPanelV767); break; } return 0; } /*=============================================================================== Llamadas del panel de control del tdc V767. ==================================================================================*/ /*---------------------------------------------------------------------------------- Subrutina de entrada del panel */ int CVICALLBACK PanelV767CallBack (int panel, int event, void *callbackData, int eventData1, int eventData2) { int iranura,ranura; int addr,dato,a1,a2,a3,a4,plant; char linea[50]; switch (event) { case EVENT_GOT_FOCUS: /* Inicializa todos los valores*/ // Obtiene el indice de ranura del VME GetCtrlIndex (handPanel_principal, PANELPR_RINGSLIDE, &iranura); ranura=iranura+1; SetCtrlVal (handPanelV767, PANV767_NUM_RANURA, ranura); //Lee los canales activos del tdc addr= base[ranura]; dato= V767_READ_ENABLE_PATTERN; EscribeRegistroMicro(addr,dato); for(a2=0;a2<8;a2++) { LeeRegistroMicro(addr,&dato); plant=1; for(a3=0;a3<16;a3++) { if(dato&plant) a4=1; else a4=0; if(a2<2) CheckListItem(handPanelV767, PANV767_LIST_CAN_1, a2*16+a3, 1); else if(a2<4)CheckListItem(handPanelV767, PANV767_LIST_CAN_2, (a2-2)*16+a3, 1); else if(a2<6)CheckListItem(handPanelV767, PANV767_LIST_CAN_3, (a2-4)*16+a3, 1); else CheckListItem(handPanelV767, PANV767_LIST_CAN_4, (a2-6)*16+a3, 1); plant=plant<<1; } } dato= V767_READ_WINDOW_WIDTH; EscribeRegistroMicro(addr,dato); LeeRegistroMicro(addr,&dato); Fmt(linea,"%s<%x",dato); StringUpperCase (linea); ReplaceListItem (handPanelV767, PANV767_LIST_VENTANA, 0, linea, 0); dato= V767_READ_WINDOW_OFFSET; EscribeRegistroMicro(addr,dato); LeeRegistroMicro(addr,&dato); Fmt(linea,"%x",dato); StringUpperCase (linea); ReplaceListItem (handPanelV767, PANV767_LIST_VENTANA, 0, linea, 0); for(a1=0;a1