/*----------------------------------------------------------------------------*/ /* coolstat: based on cadc.c program, but just write a short summary of */ /* the status of sensors which are in the cooling system interlock system */ /* */ /* 24-May-2001 JPS, based on earlier cadc program by YGK and HvH */ /* */ /* compile command -------> */ /* cc68k -c -O -DCPU=MC68020 -I$VX_VW_BASE/h coolstat.c */ /* load with: ld < /home/phoncs/mvd/vme/coolstat.o */ /*-------------------------------------------------------------------*/ /* 20-Nov-2002 setup to work on phoncs0 (i.e. change file names in comments (JPSullivan). If we have this cross compiler on phenix14, I do not know where it is. It can be compiled on phenix14. */ /* 3-Jan-03: JPS updated ADC-->Temperature calibration constants */ #include #include #include #include #include "taskLib.h" STATUS coolstat(){ int i, j, k, ichan, index, idout; int iomodule = 1; int iabcd = 3; int ipin = 17; int idebug = 0; int port[4]; int ibit, power, data; int ival[16][8] = { 0*128 }; int icon, jpin, iconn[4][16]; int icontrol[8] = { 1,0,0,0,1,0,1,0 }; /* switch to differential */ int ldebug = 0; int jcontrol[4][3] = { {0,0,0}, {0,0,1},{0,1,0}, {0,1,1} } ; /* address */ /* vvvv */ int sclk_on = 16; /* 0001 0000 bit 5 */ int din_on = 32; /* 0010 0000 bit 6 */ int output_on = 192; /* 1100 0000 <-- passive, enable */ int all_off = 192; /* 1100 0000 don't touch the output */ int both_off = 207; /* 1100 1111 '' */ int sclk_off = 239; /* 1110 1111 '' */ /* ^^ */ /* data, sstrb out */ int t_deg_c[10]; /* Temperature translated to degrees C, T1-T10 */ /* Temperature calibration factors, T1-T10, are based on leaving the system*/ /* off overnight and then assuming they had all reached an equilibrium */ /* temperature which was the room temperature. */ /* Because this processor can only do integer arithmetic, the numbers */ /* below were multiplitied by 100. That is, instead of 5.23, 523 is */ /* used. The temperature in degrees K is the ADC value/5.23 (for example). */ /* Values until 3-Jan-03: */ /* int t_calib[10] = { 523,517,518,249,536,528,529,522,533,530}; */ /* New values 3-Jan-03: */ int t_calib[10] = { 523,517,518,251,536,528,519,526,533,530}; /* Temperature status ADC -- cut which defines good (above this number) */ /* or bad (below this number) -- separate value for each T sensor */ int t_status_cut[10] = {1500,1500,1500,1500,1500,1500,1500,1500,1500,1500}; /* For the flow status, only one number is used for all channels */ int f_status_cut = 1500; /* Index for the first and second indeces in the iconn array which */ /* correspond to T1 ... T10. */ int iconn_ind1[10]={3, 3, 3, 2, 2, 1, 1, 1, 0, 0}; int iconn_ind2[10]={2, 7,12, 4, 7, 2, 7,12, 4, 7}; /* these are indeces for the flow sensors */ /* int iconn_ind3[10]={3, 3, 3, 0, 0, 1, 1, 1, 2, 2}; */ /* int iconn_ind4[10]={3, 8,13, 8,10, 3, 8,13, 8,10}; */ int iconn_ind3[10]= {3, 3, 3, 0, 0, 1, 1, 1, 3, 2}; int iconn_ind4[10]= {3, 8,13, 8,10, 3, 8,13, 9,10}; int nt_sensor; /* index for temperature sensor number */ int nf_sensor; /* index for flow sensor number */ /*---------------------------------------------------------------------------*/ data = output_on; /* enable ouput lines: */ io_write2(iomodule,iabcd,ipin,data,idebug); for ( i = 0 ; i <16 ; i++ ) for ( j = 0 ; j < 8 ; j++ ) ival[i][j] = 0; data = all_off; io_write2(iomodule,iabcd,ipin,data,idebug); for ( i = 0; i < 16 ; i++ ){ /* loop over 16 ADCs (0-16)*/ data = data | i ; io_write2(iomodule,iabcd,ipin,data,idebug); /* for ( ichan = 0; ichan < 8 ; ichan++ ){ loop over channels */ for ( ichan = 0; ichan < 4 ; ichan++ ){ /* now only 0-3 */ for ( j = 0 ; j < 3 ; j++ ) icontrol[j+1] = jcontrol[ichan][j]; for ( k = 0 ; k < 8 ; k++ ){ /* clock out control bits */ if ( icontrol[k] == 0 ) { data = data & both_off; io_write2(iomodule,iabcd,ipin,data,idebug); } if ( icontrol[k] == 1 ) { data = data | din_on; data = data & sclk_off; io_write2(iomodule,iabcd,ipin,data,idebug); } data = data | sclk_on; io_write2(iomodule,iabcd,ipin,data,idebug); } data = data & both_off; /* din; off, sclk; off */ io_write2(iomodule,iabcd,ipin,data,idebug); data = data | sclk_on; io_write2(iomodule,iabcd,ipin,data,idebug); for ( j = 0 ; j < 16 ; j++) { data = data & sclk_off; io_write2(iomodule,iabcd,ipin,data,idebug); data = data | sclk_on; io_write2(iomodule,iabcd,ipin,data,idebug); idout = 24; io_read(iomodule,iabcd,idout,&ibit,idebug); index = 11 - j; k = 0; power = 1; while ( k < index ) { power = power << 1; k = k + 1; } ival[i][ichan] = ival[i][ichan] + ibit*power; icon = 3 - (2*(i/8) + ichan%2); jpin = (i*2 + ichan/2)%16; iconn[icon][jpin] = ival[i][ichan]; } /* end loop for 12 bits clocked out*/ /*printf("icon %d jpin %d \n", icon, jpin); */ for ( j = 0 ; j < 4 ; j++ ) { data = data | sclk_on; io_write2(iomodule,iabcd,ipin,data,idebug); data = data & sclk_off; io_write2(iomodule,iabcd,ipin,data,idebug); } /* printf("chip#,chan#,ival : %d %d %d\n",i+1,ichan,ival[i][ichan]); */ } /* loop over channels */ data = all_off; }/* loop over ADCs */ for (i=0; i<10; i++) { t_deg_c[i] = 100*iconn[iconn_ind1[i]][iconn_ind2[i]]/ t_calib[i]; t_deg_c[i] -= 273; /* T(i+1) i=0,9 */ /*printf ( " iconn[ %d ][ %d ] = %d t_deg_c = %d \n", iconn_ind1[i], iconn_ind2[i], iconn[iconn_ind1[i]][iconn_ind2[i]], t_deg_c[i] ); */ } printf("\n Sensors in MVD Cooling Interlock System \n"); printf(" sensor Temp T status | flow status\n"); printf(" location sensor (deg C) OK/bad | sensor OK/bad\n"); printf(" ------------------- ------ ---------------- | ------ ------\n"); nt_sensor=1; nf_sensor=1; i=nt_sensor-1; j=nf_sensor-1; TF_Print("East air input ", nt_sensor, iconn[iconn_ind1[i]][iconn_ind2[i]-1], t_deg_c[i], t_status_cut[i], nf_sensor, iconn[iconn_ind3[j]][iconn_ind4[j]], f_status_cut); nt_sensor=2; nf_sensor=2; i=nt_sensor-1; j=nf_sensor-1; TF_Print("East MCM air out ", nt_sensor, iconn[iconn_ind1[i]][iconn_ind2[i]-1], t_deg_c[i], t_status_cut[i], nf_sensor, iconn[iconn_ind3[j]][iconn_ind4[j]], f_status_cut ); nt_sensor=3; nf_sensor=3; i=nt_sensor-1; j=nf_sensor-1; TF_Print("East volume air out", nt_sensor, iconn[iconn_ind1[i]][iconn_ind2[i]-1], t_deg_c[i], t_status_cut[i], nf_sensor, iconn[iconn_ind3[j]][iconn_ind4[j]], f_status_cut ); nt_sensor=4; nf_sensor=9; i=nt_sensor-1; j=nf_sensor-1; TF_Print("East water in ", nt_sensor, iconn[iconn_ind1[i]][iconn_ind2[i]-1], t_deg_c[i], t_status_cut[i], nf_sensor, iconn[iconn_ind3[j]][iconn_ind4[j]], f_status_cut ); nt_sensor=5; nf_sensor=10; i=nt_sensor-1; j=nf_sensor-1; TF_Print("East water out ", nt_sensor, iconn[iconn_ind1[i]][iconn_ind2[i]-1], t_deg_c[i], t_status_cut[i], nf_sensor, iconn[iconn_ind3[j]][iconn_ind4[j]], f_status_cut ); nt_sensor=6; nf_sensor=6; i=nt_sensor-1; j=nf_sensor-1; TF_Print("West air input ", nt_sensor, iconn[iconn_ind1[i]][iconn_ind2[i]-1], t_deg_c[i], t_status_cut[i], nf_sensor, iconn[iconn_ind3[j]][iconn_ind4[j]], f_status_cut ); nt_sensor=7; nf_sensor=7; i=nt_sensor-1; j=nf_sensor-1; TF_Print("West MCM air out ", nt_sensor, iconn[iconn_ind1[i]][iconn_ind2[i]-1], t_deg_c[i], t_status_cut[i], nf_sensor, iconn[iconn_ind3[j]][iconn_ind4[j]], f_status_cut ); nt_sensor=8; nf_sensor=8; i=nt_sensor-1; j=nf_sensor-1; TF_Print("West volume air out", nt_sensor, iconn[iconn_ind1[i]][iconn_ind2[i]-1], t_deg_c[i], t_status_cut[i], nf_sensor, iconn[iconn_ind3[j]][iconn_ind4[j]], f_status_cut ); nt_sensor=9; nf_sensor=4; i=nt_sensor-1; j=nf_sensor-1; TF_Print("West water in ", nt_sensor, iconn[iconn_ind1[i]][iconn_ind2[i]-1], t_deg_c[i], t_status_cut[i], nf_sensor, iconn[iconn_ind3[j]][iconn_ind4[j]], f_status_cut ); nt_sensor=10; nf_sensor=5; i=nt_sensor-1; j=nf_sensor-1; TF_Print("West water out ", nt_sensor, iconn[iconn_ind1[i]][iconn_ind2[i]-1], t_deg_c[i], t_status_cut[i], nf_sensor, iconn[iconn_ind3[j]][iconn_ind4[j]], f_status_cut ); return(OK); } /*=======================================================================*/ int io_write2(int iomodule,int iabcd,int ipin,int data, int idebug) { /*--------------------------------------------------------------------------*/ /* This one does the write-part of the ADC protocol. 8 bits are written, */ /* - 4 bits to address a particular chip */ /* - a serial clock */ /* - serial data */ /* two additional bits return SSTRB and DOUT, and are safeguarded in */ /* the calling program by being set high, and also in this routine. */ /*-------------------------------------------------------------------*/ #define BASE 0xffff6000 int eightbits, readback, index, ibit, itemp; unsigned int *address; char c; /* see http://p25ext.lanl.gov/phenix/mvd/ancillary/logic/logic.html: */ int dout_mask[2][4] = { {0xc000c0, 0x00c000, 0xc000c0, 0xa0} , {0xb0, 0xc0, 0xd0, 0xe0} }; /*-- end declarations --------------------------------------------------------*/ address = (unsigned int *)(BASE + (iomodule-1)*0x1000 + (iabcd -1)*0x100 ); readback = *address; /* read what's there now, and */ itemp = readback; /* unshuffle bytes cdab->abcd */ readback = readback >> 16; /* shift 16 bits to the front */ readback = readback & 0x0000ffff; /* mask off the rest */ itemp = itemp << 16; /* shift first 8 bits to the */ itemp = itemp & 0xff0000; /* back, and mask off the rest*/ readback = readback | itemp; /* combine halves again */ readback = readback | dout_mask[iomodule-1][iabcd-1]; /* safeguard output lines */ eightbits = 0x000000ff; /* 8-bit mask where data goes */ eightbits = eightbits << (ipin-1); /* shift mask into place */ readback = readback & ~eightbits; /* clear 8-bit space */ data = data & 0x00000000ff; /* only 8 bits, mask rest */ data = data << (ipin-1); /* shift to ipin */ data = data | readback; /* combine old and new */ /* itemp = data; printf(" on C: (1-24) "); for (ibit=1; ibit<=24; ibit++){ index = data & 0x1; printf("%d",index); data = data >> 1; } data = itemp; */ itemp = data; /* reshuffle bytes abcd->cdab */ data = data << 16; /* shift 16 bits to the back */ data = data & 0xffff0000; /* mask off the rest */ itemp = itemp >> 16; /* shift 8 bits to the front, */ itemp = itemp & 0x000000ff; /* and mask off the rest */ data = data | itemp; /* combine them again */ *address = data; /* load the bits */ /* printf(" (end of write) ready? "); while ((c = getchar()) != '\n') { } */ } /* end io_write2 */ /*============================================================================*/ int io_read(int iomodule,int iabcd,int ipin, int *ibit, int idebug) { /*----------------------------------------------------------------------------*/ /* Do a 'direct read' of one bit from a given connector. This is done from */ /* a word in memory 1 higher than where you do a 'write'. Also, for this */ /* work, the bit in the 'write' register must be kept high (=passive). */ /* June 2000 Hubert van Hecke LANL */ /*-----------------------------------------------------------------------*/ #define BASE 0xffff6000 int readback, itemp; unsigned int *address; /*-- end declarations --------------------------------------------------------*/ address = (unsigned int *)(BASE + (iomodule-1)*0x1000 + (iabcd -1)*0x100 ); address = address + 1; /* 'direct read' see pgs 3,15 */ readback = *address; /* read what's there now */ itemp = readback; /* make a copy */ readback = readback >> 16; /* shift 16 bits to the front */ readback = readback & 0xffff; /* mask off the rest */ itemp = itemp << 16; /* shift first 8 bits to the */ itemp = itemp & 0xff0000; /* back, and mask off the rest*/ readback = readback | itemp; /* combine them again */ readback = readback >> (ipin-1); /* shift bit to position 1 */ readback = readback & 0x1; /* mask off the rest */ *ibit = readback; /* copy to output argument */ } /* end of io_read */ /*============================================================================*/ int TF_Print ( char *name_of_line, int it, int raw_t_stat, int t_deg_c, int t_status_cut, int iflow, int raw_f_stat, int f_status_cut ) { /* Output one line related to temperature sensor status */ /* JPSullivan 24-May-2001 */ printf(" %s T%2d %4d ", name_of_line, it, t_deg_c ); if ( raw_t_stat > t_status_cut ) { printf ( " OK "); } else { printf ( " Bad"); } printf ( " | F%2d ", iflow); if ( raw_f_stat > f_status_cut ) { printf ( " OK\n"); } else { printf ( " Bad\n"); } return 0; }