/* relay.c started from relay.c March 2000 HvH This program is to address the control lines on the relay board. See http://p25ext.lanl.gov/phenix/mvd/ancillary/logic/logic.html for the pin assignments (I/O module 1, group D, lines 1-9 (East) and 10-18 (West) This version works with phoncs:/home/mvd/vme/mon_gui.pl The 9 bits are for: 1 reset 2 chiller 1 on 3 chiller 2 on 4 fan on 5 pump on 6 LV on 7 fann off 8 pump off 9 LV off 10 unused 20-Nov-2002 setup to work on phoncs0 (i.e. change file names in open statements and comments (JPSullivan). If we have this cross compiler on phenix14, I do not know where it is. It can be compiled on phenix14. This program is compiled with: make -f relay_mon.makefile Load into iocondev8 with: ld #include #include #include #include "taskLib.h" STATUS relay_mon (int iew, int item, int onoff) { /* iew=0: east, iew=1: west */ #define BASE 0xffff6000 int iomodule = 1; /* defaults at startup: */ int iabcd = 4; /* connector D */ int ipin = 15; /* first pin for east */ int go_on = 1; /* command loop control */ int lok, itmp, idata[2], jdata, readback, ieastw, ipin_sav; char command[32],atmp[32],aonoff[5],aew[5],aeastw[5],astat[5]; unsigned int *data; int reset_on = 0x0001; /* bit 1 */ int ch1_on = 0x0002; /* bit 2 */ int ch2_on = 0x0004; /* bit 3 */ int fan_on = 0x0008; /* bit 4 */ int fan_off = 0x0040; /* bit 7 */ int pump_on = 0x0010; /* bit 5 */ int pump_off = 0x0080; /* bit 8 */ int lv_on = 0x0020; /* bit 6 */ int lv_off = 0x0100; /* bit 9 */ /*----------------------------------------------------------------------------*/ printf("relay_mon:: East/West: %d, item: %d, on/off: %d \n",iew, item, onoff); if (iew==0){ /* east */ ipin = 15; /* For the pin mapping: (see above) */ } else if (iew==1) { ipin = 5; /* west */ } strcpy(command , "xxx"); if (item==0) {strcpy(command , "reset");} else if (item==1) {strcpy(command , "chiller1");} else if (item==2) {strcpy(command , "chiller2");} else if (item==3) {strcpy(command , "fan");} else if (item==4) {strcpy(command , "pump");} else if (item==5) {strcpy(command , "lv");} strcpy(aew , "East"); /* default at startup */ if (iew==1) {strcpy(aew,"West");} /* 0=east, 1=west */ relay_read(iomodule,iabcd,&idata[iew]) ; printf("idata[raw]= %x ", idata[iew]); itmp = idata[iew]; idata[0] = (idata[iew]>> 15-1) & 0x03ff; idata[1] = (itmp >> 5-1) & 0x03ff; printf(" idata[east]= %x , idata[west]= %x \n",idata[0],idata[1]); if ( strncmp(command,"reset",5)==0 ) { /* execute command */ printf("%s reset going on and off \n", aew); idata[iew] = idata[iew] | reset_on; relay_write(iomodule,iabcd,ipin,idata[iew]); idata[iew] = idata[iew] & ~reset_on; relay_write(iomodule,iabcd,ipin,idata[iew]); } else if ( strncmp(command,"chiller1",8)==0 ) { if (onoff==1) { printf("%s chiller 1 forced on \n", aew); idata[iew] = idata[iew] | ch1_on; relay_write(iomodule,iabcd,ipin,idata[iew]); } else if (onoff==0) { printf("%s chillers can only be forced on, or set on auto \n", aew); } else if (onoff==2) { printf("%s chiller 1 going to automatic \n", aew); idata[iew] = idata[iew] & ~ch1_on; relay_write(iomodule,iabcd,ipin,idata[iew]); } } else if ( strncmp(command,"chiller2",8)==0 ) { if (onoff==1) { printf("%s chiller 2 forced on \n", aew); idata[iew] = idata[iew] | ch2_on; relay_write(iomodule,iabcd,ipin,idata[iew]); } else if (onoff==0) { printf("%s chillers can only be forced on, or set on auto \n", aew); } else if (onoff==2) { printf("%s chiller 2 going to automatic \n", aew); idata[iew] = idata[iew] & ~ch2_on; relay_write(iomodule,iabcd,ipin,idata[iew]); } } else if ( strncmp(command,"fan",3)==0) { if (onoff==1 ) { printf("%s fan forced on \n", aew); idata[iew] = idata[iew] | fan_on; idata[iew] = idata[iew] & ~fan_off; relay_write(iomodule,iabcd,ipin,idata[iew]); } else if (onoff==0 ) { printf("%s fan forced off \n", aew); idata[iew] = idata[iew] & ~fan_on; idata[iew] = idata[iew] | fan_off; relay_write(iomodule,iabcd,ipin,idata[iew]); } else if (onoff==2) { printf("%s fan going on automatic \n", aew); idata[iew] = idata[iew] & ~fan_on; idata[iew] = idata[iew] & ~fan_off; relay_write(iomodule,iabcd,ipin,idata[iew]); } } else if ( strncmp(command,"pump",4)==0) { if (onoff==1) { printf("%s pump forced on \n", aew); idata[iew] = idata[iew] | pump_on; idata[iew] = idata[iew] & ~pump_off; relay_write(iomodule,iabcd,ipin,idata[iew]); } else if (onoff==0) { printf("%s pump forced off \n", aew); idata[iew] = idata[iew] & ~pump_on; idata[iew] = idata[iew] | pump_off; relay_write(iomodule,iabcd,ipin,idata[iew]); } else if (onoff==2) { printf("%s pump going on automatic \n", aew); idata[iew] = idata[iew] & ~pump_on; idata[iew] = idata[iew] & ~pump_off; relay_write(iomodule,iabcd,ipin,idata[iew]); } } else if ( strncmp(command,"lv",2)==0) { if (onoff==1) { printf("%s lv forced on \n", aew); idata[iew] = idata[iew] | lv_on; idata[iew] = idata[iew] & ~lv_off; relay_write(iomodule,iabcd,ipin,idata[iew]); } else if (onoff==0) { printf("%s lv forced off \n", aew); idata[iew] = idata[iew] & ~lv_on; idata[iew] = idata[iew] | lv_off; relay_write(iomodule,iabcd,ipin,idata[iew]); } else if (onoff==2) { printf("%s lv going on automatic \n", aew); idata[iew] = idata[iew] & ~lv_on; idata[iew] = idata[iew] & ~lv_off; relay_write(iomodule,iabcd,ipin,idata[iew]); } } else if ( strncmp(command,"xxx",3)==0) { printf(" null, refresh or invalid command given \n"); } /* end of execute command, now read back and display: */ strcpy(aeastw , "East"); /* default at startup */ ipin_sav = ipin; ipin = 15; /* For the pin mapping: (see above) */ for (ieastw=0; ieastw<=1; ieastw++) { if (ieastw==1) { strcpy(aeastw,"West"); ipin = 5; } /* 0=east, 1=west */ relay_read(iomodule,iabcd,&jdata) ; jdata = jdata >> ipin-1; printf(" east / west %4s",aeastw); printf(" 0 reset "); if ((jdata & ch1_on) == 0){ strcpy(astat,"auto");} else { strcpy(astat,"on ");} printf(" 1 chiller1 on/auto %5s ",astat); if ((jdata & ch2_on) == 0){ strcpy(astat,"auto");} else { strcpy(astat,"on ");} printf(" 2 chiller2 on/auto %5s ",astat); if ( ((jdata & fan_on ) != 0) && ((jdata & fan_off) == 0)){ strcpy(astat,"on ");} else if ( ((jdata & fan_on ) == 0) && ((jdata & fan_off) != 0)){ strcpy(astat,"off ");} else if ( ((jdata & fan_on ) == 0) && ((jdata & fan_off) == 0)){ strcpy(astat,"auto");} else { strcpy(astat," ?? ");} printf(" 3 fan on/off/auto %5s ",astat); if ( ((jdata & pump_on ) != 0) && ((jdata & pump_off) == 0)){ strcpy(astat,"on ");} else if ( ((jdata & pump_on ) == 0) && ((jdata & pump_off) != 0)){ strcpy(astat,"off ");} else if ( ((jdata & pump_on ) == 0) && ((jdata & pump_off) == 0)){ strcpy(astat,"auto");} else { strcpy(astat," ?? ");} printf(" 4 pump on/off/auto %5s ",astat); if ( ((jdata & lv_on ) != 0) && ((jdata & lv_off) == 0)){ strcpy(astat,"on ");} else if ( ((jdata & lv_on ) == 0) && ((jdata & lv_off) != 0)){ strcpy(astat,"off ");} else if ( ((jdata & lv_on ) == 0) && ((jdata & lv_off) == 0)){ strcpy(astat,"auto");} else { strcpy(astat," ?? ");} printf(" 5 lv on/off/auto %5s \n",astat); } /* display loop over east/west */ ipin = ipin_sav; return(OK); /* end of relay.c */ } /*============================================================================*/ int relay_write(int iomodule,int iabcd,int ipin,int data) { /*--------------------------------------------------------------------------*/ /* This one does the write-part of the relay board controls. */ /*-------------------------------------------------------------------*/ #define BASE 0xffff6000 int tenbits, 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} };*/ int dout_mask[2][4] = { {0x000000, 0x000000, 0x000000, 0x00} , {0x00, 0x00, 0x00, 0x00} }; /*-- 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 */ tenbits = 0x000003ff; /* 10-bit mask for data */ tenbits = tenbits << (ipin-1); /* shift mask into place */ readback = readback & ~tenbits; /* clear 10-bit space */ data = data & 0x00000003ff; /* only 10 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 relay_write */ /*============================================================================*/ int relay_read(int iomodule,int iabcd,int *idata) { /* */ /* This routine passes back a 24-bit word *idata which contains the status */ /* of the pins of module 'iomodule', connector 'iabcd'. */ /* * /* June 2000 Hubert van Hecke */ /*----------------------------------------------------------------------------*/ #define BASE 0xffff6000 int onebit=1, readback, itemp; unsigned int *address; /*-- end declarations --------------------------------------------------------*/ /* calculate target address: */ 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 */ *idata = readback; /* copy to output argument */ } /* end io_read */ /*============================================================================*/