#include #include #include #include #include "a200.h" /* definitions relative to the CAEN system */ short n_raw_data, raw_data[564]; struct a200_err_tab{ int nr; char *msg; } a200_err[] = { 0, "OK", /* G : general error S : Power supply error ( SY 127 ) D : Distributor error ( SY 227 ) A : Application programs */ -1, "G: invalid assignment of a Channel or Crate number", -2, "G: attempt to START_READOUT without a previous SELECT_TARGET", -3, "G: attempt to WRITE_DATA without a previous SELECT_TARGET", -4, "S: attempt to change a Status bit different from ON/OFF", -5, "S: attempt to write a Read-only parameter ( Subadress > 8 )", -6, "S: attempt to assign a channel to a non existing group", -7, "S: attempt to write the Total Time of a Streamer-tube-conditioning", -8, "S: attempt to Start, Stop or Pause the LST conditioning", -9, "S: attempt to WRITE_DATA with subadd. >7 when GAG was selected", -10, "S: attempt to use a bit different from 0 when writing the Status", -11, "S: attempt to WRITE_DATA with subadd > 6 when GRG was selected", -12, "S: error on setting protection bit", -32, "G: attempt to select a non-existing channel", -33, "G: attempt to write a too low value for a parameter", -34, "G: attempt to write a too high value for a parameter", -35, "D: attempt to change ON/OFF Hv different from bit 0", -36, "D: attempt to switch on with HV IN present", -37, "D: attempt to change Pulse Test EN/DIS different from bit 0", -38, "D: attempt to change Password EN/DIS different from bit 0", -48, "G: attempt to use a not yet implemented function", -256, "G: attempt to select a non-existing Crate", TIMOUT, "A: Timout to accept a command ", -1001, "A: Reading ALL ch of SY227 first word != slot number" -1002, "A: ndata != 1 reading one word ( HV_Read_One )" -1003, "A: ndata < 3 reading a group ( HV_Read_Group ) " }; int a200_err_tab_size = 26; struct sy127_ch_type_tab{ int code; char *name; float vmax; /* Maximum V in Volts ( absolute value ) */ float imax; /* Maximum I in Milliamps */ float vres; /* resolution in Volts */ float ires; /* resolution in microamps */ } sy127_ch_type[] = { /* the order is the same as the one in the A200 manual */ 6, "800 Volts, 500 mmA", 800., 500., .2, .2, 0, " 2 KVolts, 3 mA", 2000., 3., .5, 1., 1, " 3 KVolts, 3 mA", 3000., 3., 1., 1., 14, " 3 KVolts, 3 mA", 3000., 3., 1., 1., /* alias */ 3, " 4 KVolts, 2 mA", 4000., 3., 1., 1., 15, " 4 KVolts, 2 mA", 4000., 2., 1., 1., /* alias */ 5, " 6 KVolts, 1 mA", 6000., 1., 2., 1., 12, " 6 KVolts, 1 mA", 6000., 1., 1., 1., /* alias */ 4, "8 KVolts, 500 mmA", 8000., 0.5, 2., 1., 7, "8 KVolts, 200 mmA", 8000., 0.2, 2., .1, 18, "8 KVolts, 200 mmA", 8000., 0.2, 2., .1, /* alias */ 8, "6 KVolts, 200 mmA", 6000., 0.2, 2., .1, 11, "4 KVolts, 200 mmA", 4000., 0.2, 1., .1, 10, "2 KVolts, 200 mmA", 2000., 0.2, .5, .1, 9, "200Volts, 200 mmA", 200., 0.2, .1, .1, 13, "Special Module ", 0., 0., 0., 0., 16, "800Volts, 200 mmA", 800., 0.2, .2, .2, 19, "10 KVolts, 1 mA", 10000., 1., 3., 1., 22, "10 KVolts, 200 mmA", 200., 0.2, 3., .1, 23, "15 KVolts, 200 mmA",15000., 0.2, 1., 1., 24, "15 KVolts, 1 mA", 15000., 1., 4., 1., 31, "I/O Module ", 0., 0., 0., 0. }; int sy127_ch_type_tab_size = 22; HV_Read(param, ncrate, chan, data, ndata) short ncrate, chan, param; short data[], *ndata; { int code; char *caller = "HV_Read"; sem_wait(ev_id, caller); if( (code = Sel_Targ(ncrate, chan)) == TIMOUT){ sem_free(ev_id, caller); return code; } if ( code = check_OK() ){ sem_free(ev_id, caller); return code; } if ( (code = Start_Readout(param)) == TIMOUT ){ sem_free(ev_id, caller); return code; } code = Read_Values(data, ndata); sem_free(ev_id, caller); return code; } HV_Set(param, ncrate, chan, value) short ncrate, chan, param, value; { int code; char *caller = "HV_Set"; sem_wait(ev_id, caller); if( (code = Sel_Targ(ncrate, chan)) == TIMOUT){ sem_free(ev_id, caller); return code; } if ( code = check_OK() ){ sem_free(ev_id, caller); return code; } if ( (code = Write_Data(value, param)) == TIMOUT ){ sem_free(ev_id, caller); return code; } code = check_OK(); sem_free(ev_id, caller); return code; } D_Read(param, ncrate, slot, chan, data, ndata) short ncrate, slot, chan, param; short data[], *ndata; { int i, code; int err_code = -1001; char *caller = "D_Read"; sem_wait(ev_id, caller); if( (code = Sel_Targ(ncrate, chan)) == TIMOUT){ sem_free(ev_id, caller); return code; } if ( code = check_OK() ){ sem_free(ev_id, caller); return code; } if ( (code = Write_Data(slot, D_SLOT_SEL)) == TIMOUT ){ sem_free(ev_id, caller); return (code); } if ( code = check_OK() ){ sem_free(ev_id, caller); return code; } if ( (code = Start_Readout(param)) == TIMOUT ){ sem_free(ev_id, caller); return (code); } if ( chan == ALL ) (*ndata)++; if (code = Read_Values(data, ndata)){ sem_free(ev_id, caller); return code; } sem_free(ev_id, caller); if ( chan == ALL){ /* if ALL check that first word == slot_nr */ if ( data[0] != slot){ return err_code; } else { (*ndata)--; for ( i = 0; i < *ndata; i++) data[i] = data[i+1]; } } return 0; } D_Set(param, ncrate, slot, chan, value) short param, ncrate, slot, chan, value; { int code; char *caller = "D_Set"; sem_wait(ev_id, caller); if( (code = Sel_Targ(ncrate, chan)) == TIMOUT){ sem_free(ev_id, caller); return code; } if ( code = check_OK() ){ sem_free(ev_id, caller); return code; } if ( (code = Write_Data(slot, D_SLOT_SEL)) == TIMOUT ){ sem_free(ev_id, caller); return (code); } if ( code = check_OK() ){ sem_free(ev_id, caller); return code; } if ( param != D_Z_I_SET ){ if ( (code = Write_Data(value, param)) == TIMOUT ){ sem_free(ev_id, caller); return (code); } } else { Write_Data(value, param); sleep (30); } code = check_OK(); sem_free(ev_id, caller); return code; } HV_Read_One(param, ncrate, chan, value) short ncrate, chan, param; short *value; { int i, code; int err_code= -1002; n_raw_data = 2; if (code = HV_Read(param, ncrate, chan, raw_data, &n_raw_data)) return code; if (n_raw_data != 1) return err_code; *value = raw_data[0]; return 0; } HV_Read_Group(param, ncrate, group, values, nvalues, map) short ncrate, group, param; short values[], *nvalues, map[]; { int i, code; int err_code= -1003; n_raw_data = *nvalues + 3; if (code = HV_Read(param, ncrate, group, raw_data, &n_raw_data)) return code; if (n_raw_data < 3) return err_code; decode_map(raw_data, map); *nvalues = n_raw_data - 3; for ( i = 0; i < *nvalues; i++) values[i] = raw_data[i + 3]; return 0; } HV_Map(ncrate) /* reads the group assignement of channels */ short ncrate; { int i, j, code; short nvalues, values[40], map[40]; nvalues = 40; code = HV_Read_Group(CH_TO_GR_ASS, ncrate, ALL, values, &nvalues, map); if(code != 0){ printf(" HV_map : error %d, trying to make the SY127 HV Map \n",code); return -1; } for ( i = 0; i < 40; i++) for ( j = 0; j < 8; j++) group_ch[ncrate][j][i/16] = 0; for ( i = 0; i < 40; i++) if ( map[i] ) for ( j = 0; j < 8; j++) if ( values[i] & ( 1 << j ) ) group_ch[ncrate][j][i/16] |= 1 << ( i - ( (i / 16) * 16 ) ) ; /* for each group 40 bits ( 2 1/2 short words ) give the channel associated to the group */ } /***************************************************************************/ A200_init() { short code; char *caller = "A200_init"; fpermit( A200_BASE, 0x100); if ( !sem_exist(A200_event) ){ ev_id = sem_link_cr(A200_event, caller); code = A200_reset(); return (code); } else { ev_id = sem_link_cr(A200_event, caller); return 0; } } A200_reset() { short code; short *p; char *caller = "A200_reset"; sem_wait(ev_id, caller); p = (short *) (A200_BASE | RESET); *p = NULL; code = *p & 1; tsleep(T300); sem_free (ev_id, caller); return (code); } void A200_end() { char *caller = "A200_end"; sem_unl_del(ev_id, A200_event, caller); } Sel_Targ(ncrate, target) short ncrate, target; { short *p, check, value; int count = 0; p = (short *) (A200_BASE | SEL_TARG); value = (ncrate << 8) | target; do{ count++; *p = value; *(p + 1) = NULL; } while ( ((*(p + 1) & 1) == 1) && count < TIMOUT); return count; } Read_Err_Flag(err_code) int *err_code; { short caen_err, check; short *p; int count = 0; p = (short *) (A200_BASE | READ_VAL); do { count++; tsleep(WAIT_SOME_MS); caen_err = *p; check = *(p + 1); } while ( ((check & 1) == 1) && count < READ_MAX_TRY); if ( count == READ_MAX_TRY) return (int) TIMOUT; else { *err_code = (int) caen_err; return 0; } } Write_Data(data, param) short data; short param; { short check; short *p; int count = 0; p = (short *) (A200_BASE | WRITE_DATA); do{ count++; *p = data; *(p + 1) = param; } while ( ((*(p + 1) & 1) == 1) && count < TIMOUT); return count; } Start_Readout(param) short param; { short val; short *p; int count = 0; p = (short *) (A200_BASE | START_RD); do{ count++; *p = READOUT; *(p + 1) = param; } while ( ((*(p + 1) & 1) == 1) && count < TIMOUT); return count; } Read_Values( data, ndata) short data[]; short *ndata; { short *p; short check; short count = 0; short ndata_max = 564; if ( *ndata < ndata_max) ndata_max = *ndata; *ndata = 0; p = (short *) (A200_BASE | READ_VAL); do { count++; tsleep(WAIT_SOME_MS); data[0] = *p; check = *(p + 1); } while ( ((check & 1) == 1) && count < READ_MAX_TRY); if ( count == READ_MAX_TRY) return (int) TIMOUT; *ndata = 1; do { data[*ndata] = *p; check = *(p + 1); } while ( (check & 1) == 0 && ++(*ndata) < ndata_max ); if ( (data[0] & 0x8000 ) && *ndata == 1) return (int) data[0]; return 0; } check_OK() { int code, err_code; if ( (code = Read_Err_Flag(&err_code)) == TIMOUT ){ return (code); } else return (err_code); } char *A200_Error(nerr) short nerr; { char *error; int i; char *boh = " unknown error code"; error = boh; for ( i = 0; i < a200_err_tab_size; i++) if (nerr == a200_err[i].nr) error = a200_err[i].msg; return error; } void HV_ch_type(code, name, vmax, imax, vres, ires) short code; char **name; float *vmax, *imax, *vres, *ires; { int i; char *boh = " unknown module"; *name = boh; *vmax = -1.; *imax = -1.; *vres = -1.; *ires = -1.; for ( i = 0; i < sy127_ch_type_tab_size; i++) if ((code & 31) == sy127_ch_type[i].code){ *name = sy127_ch_type[i].name; *vmax = sy127_ch_type[i].vmax; *imax = sy127_ch_type[i].imax; *vres = sy127_ch_type[i].vres; *ires = sy127_ch_type[i].ires; } } int ch_exist(crate, ch) short crate, ch; { short map[40]; decode_map(&group_ch[crate][0][0], map); return (int) map[ch]; } int tot_ch( crate, group) short crate, group; { int i; int ntot = 0; short map[40]; get_map( crate, group, map); for ( i = 0; i < 40; i++) ntot += map[i]; return ntot; } int get_map( crate, group, map) short crate, group, map[]; { int i, j; if (group >= ALL && group <= GAG_G) j = group - ALL; else if (group >= GRG_ALL && group <= GRG_G) j = group - GRG_ALL; else return -1; decode_map(&group_ch[crate][j][0], map); return 0; } decode_map( codes, map) short codes[3]; short map[40]; { int i, j, k; for ( i = 0; i < 40; i++){ map[i] = 0; j = 0; if ( i >= 16 && i < 32) j = 1; if ( i >= 32) j = 2; k = i - j * 16; if (codes[j] & ( 1 << k )) map[i] = 1; } return 0; }