/* Compile line: gcc -o altro-errors{,.c} -I../TPCrdo_new/rcu -I../TPCrdo_new/fec -I/date/rorc -I/date/fec /date/rorc/Linux/{rorc_lib_q,rorc_ddl_q,rorc_aux}.o /date/fec/Linux/fec2rorc_lib.o -L../TPCrdo_new/rcu -L../TPCrdo_new/fec -L../TPCrdo_new/tools -lrcu -lfec -ltools */ #include #include #include #include /* for RCU lib */ #include /* for chan_key */ #include #include int FEC_B_Read(u_int fec_add, u_int ch_add, u_int reg_add, u_int *reg_data); chan_key *rorc; //u_int packageId=102; //u_int traceLevel=0; extern u_int packageId; extern u_int traceLevel; const char *argp_program_version= "altro-error -0.1"; const char *argp_program_bug_address= ""; static const char doc[]= "Read out all altro error registers."; #define OPT_DDL_SERIAL 1 #define OPT_DDL_REVISION 2 #define OPT_DDL_CHANNEL 3 static const struct argp_option options[]={ {"partition", 'p',"PARTITION", 0,"Use this partition"}, {"fecs", 'f',"FEC1[,FEC2...]",0,"Use these FECs"}, {"altros", 'a',"ALTRO1[,ALTRO2...]",0,"Use these ALTROs" " (for each selected card, though)"}, {"ddl-serial", OPT_DDL_SERIAL,"SERIAL_NUMBER",0,"Use this RORC"}, {"ddl-revision", OPT_DDL_REVISION,"REVISION",0,"Use this revision"}, {"ddl-channel", OPT_DDL_CHANNEL,"CHANNEL",0,"Use this DDL-channel"}, { 0 } }; struct arguments { rorc_node_t node; unsigned int fecs; unsigned int altros; unsigned int channels; int partition; }; static error_t parse_opt(int key,char *arg,struct argp_state *state) { int ret,i; FILE *f; const char *env; char varname[100]; struct arguments *arguments=(struct arguments*)state->input; int warn_mixed=0; char *token; char *arg_copy; switch (key) { case 'f': arguments->fecs=0x00000000; arg_copy=strdup(arg); token=strtok(arg_copy,","); do { int fec=atoi(token); if (0<=fec&&fec<=31) arguments->fecs|=1<altros=0x00; arg_copy=strdup(arg); token=strtok(arg_copy,","); do { int altro=atoi(token); if (0<=altro&&altro<=7) arguments->altros|=1<node.serial=atoi(arg); break; case OPT_DDL_REVISION: arguments->node.revision=atoi(arg); break; case OPT_DDL_CHANNEL: arguments->node.channel=atoi(arg); break; case 'p': if (arguments->partition!=-1) { fprintf(stderr,"error: partition may be set only once.\n"); exit(1); } arguments->partition=atoi(arg); if (!(0<=arguments->partition&&arguments->partition<=5)) { fprintf(stderr,"error: invalid argument: no such partition: %s\n",arg); exit(1); } break; case ARGP_KEY_END: if (arguments->fecs==0x00000000) { switch(arguments->partition) { case 0: arguments->fecs=0x1ff01ff; break; case 1: arguments->fecs=0xfff1fff; break; case 2: arguments->fecs=0x1ff01ff; break; case 3: arguments->fecs=0x3ff03ff; break; case 4: arguments->fecs=0x3ff03ff; break; case 5: arguments->fecs=0x3ff03ff; break; case -1: fprintf(stderr,"error: Neigther partition nor FEC specified.\n"); exit(1); break; } } if (!(arguments->node.serial==-1 &&arguments->node.revision==-1 &&arguments->node.channel==-1 || arguments->node.serial!=-1 &&arguments->node.revision!=-1 &&arguments->node.channel!=-1)) { warn_mixed=1; } if (arguments->node.serial==-1) { if (arguments->partition!=-1) { sprintf(varname,"RORC_SERIAL%d",arguments->partition); if (env=getenv(varname)) arguments->node.serial=atoi(env); else { fprintf(stderr,"No serial number specified (neigther via the" " commandline, nor via the environment variable \"%s\".\n", varname); exit(1); } } else { fprintf(stderr,"No serial number specified and no partion given to" " get it from the environment.\n"); exit(1); } } if (arguments->node.revision==-1) { if (arguments->partition!=-1) { sprintf(varname,"RORC_REVISION%d",arguments->partition); if (env=getenv(varname)) arguments->node.revision=atoi(env); else { fprintf(stderr,"No revision specified (neigther via thecommandline," " nor via the environment variable \"%s\".\n",varname); exit(1); } } else { fprintf(stderr,"No revision number specified and no partion given to" " get it from the environment.\n"); exit(1); } } if (arguments->node.channel==-1) { if (arguments->partition!=-1) { sprintf(varname,"RORC_CHANNEL%d",arguments->partition); if (env=getenv(varname)) arguments->node.channel=atoi(env); else { fprintf(stderr,"No channel number specified (neigther via the" " commandline, nor the via environment variable \"%s\".\n", varname); exit(1); } } else { fprintf(stderr,"No channel number specified and no partion given to" " get it from the environment.\n"); exit(1); } } if (warn_mixed) { printf("warning: DDL serial number, revision and channel are defined" " partly via the\n" " commandline and partly via theenvironment.\n" " Are you sure that is what you want?\n"); } break; default: return ARGP_ERR_UNKNOWN; } return 0; } static struct argp argp={options,parse_opt,0,doc}; void read_errors(unsigned int fecs,unsigned int altros) { int ret; int i; unsigned long active_fecs; unsigned int erstr; int fec,altro,channel,reg; ret=RCU_ACTFECLIST_Read(&active_fecs); if (ret) { fprintf(stderr,"RCU_ACTFECLIST_Read failed and returned: %d\n",ret); exit(1); } if (RCU_FECERRA_Get()) { fprintf(stderr,"RCU_FECERRA_Get failed and returned: %d\n",ret); exit(1); } if (RCU_FECERRB_Get()) { fprintf(stderr,"RCU_FECERRB_Get failed and returned: %d\n",ret); exit(1); } if (RCU_RDOERR_Get()) { fprintf(stderr,"RCU_RDOERR_Get failed and returned: %d\n",ret); exit(1); } if (RCU_ALTROBUS_Get()) { fprintf(stderr,"RCU_ALTROBUS_Get failed and returned: %d\n",ret); exit(1); } if (RCU_RCUBUSBUSY_Get()) { fprintf(stderr,"RCU_BUSBUSY_Get failed and returned: %d\n",ret); exit(1); } if (RCU_ERROR_CNT_Get()) { fprintf(stderr,"RCU_ERROR_CNTx_Get failed and returned: %d\n",ret); exit(1); } for (fec=0;fec<32;++fec) if (fecs&(1<\nFec_Add = 0x%x\nCh_Add = 0x%x\nReg_Add = 0x%x", \ fec_add, ch_add, reg_add)); /* Prepare and write Instruction Sequence into the IMEM */ address = FEC_Address_Build(1, NBCAST, fec_add, ch_add, reg_add); ret = FEC_Sequence_Build(FEC_RD, address, 0, imem_data); DEBUG_TEXT(P_ID_FEC, 50, ("FEC_ALTRO_Read()>\nimem_data[0] = 0x%x\nimem_data[1] = 0x%x\n", \ imem_data[0], imem_data[1])); ret = RCU_IMEM_Write(0, FEC_RD_LEN, imem_data); if (ret) { DEBUG_TEXT(P_ID_FEC, 5 , ("FEC_ALTRO_Read()>\tRCU_IMEM_Write fail: returned value = %d", ret)); return(RCU_LIB_FAIL); } /* Execute Instruction Sequence */ ret = RCU_Exec_EXECSEQ(); if (ret) { DEBUG_TEXT(P_ID_FEC, 5 , ("FEC_ALTRO_Read()>\tRCU_Exec_Sequence() fail: returned value = %d", ret)); return(RCU_LIB_FAIL); } /* Checking if the result is ready */ /* ts_delay(1000); *//* temporary! discuss with Attiq and Changzhou */ usleep(1000); /* Reading the result */ ret = RCU_RESM_Read(0, 3, resm_data); if (ret) { DEBUG_TEXT(P_ID_FEC, 5 , ("FEC_ALTRO_Read()>\tRCU_RESM_Read() fail: returned value = %d", ret)); return(RCU_LIB_FAIL); } /* Checking the result */ if( ((resm_data[0] >> 20) & 0xf) != FEC_RD ) { DEBUG_TEXT(P_ID_FEC, 5, ("FEC_ALTRO_Read()>\nFEC_RD result not found in RESM")); return(FEC_ALTRO_Read_FAIL); } else if((resm_data[0] >> 19) & 0x1) { DEBUG_TEXT(P_ID_FEC, 5, ("FEC_ALTRO_Read()>\nFEC_RD failed!\nError Code = 0x%x", resm_data[1])); return(FEC_ALTRO_Read_FAIL); } else *reg_data = resm_data[1] & 0xfffff; DEBUG_TEXT(P_ID_FEC, 30, ("FEC_ALTRO_Read()> SUCCESSFUL!")); return(FEC_LIB_SUCCESS); }