/* relay.c started from analog_spy.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) 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 This program is compiled with cc68k -c -O -DCPU=MC68020 -I$VX_VW_BASE/h relay.c ld #include #include #include #include "taskLib.h" STATUS relay() { #define BASE 0xffff6000 int iomodule = 1; /* defaults at startup: */ int iabcd = 4; /* connector D */ int iew = 0; /* 0=east, 1=west */ int ipin = 15; /* first pin for east */ int go_on = 1; /* command loop control */ int lok, itmp, idata[2], jdata, readback; char command[32],atmp[32],aonoff[5],aew[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 */ /*----------------------------------------------------------------------------*/ strcpy(command , "help"); strcpy(aew , "East"); /* default at startup */ 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]); printf(" old status: %4x \n", idata[iew]); while(go_on){ if ( strncmp(command, "help",4)==0 | strncmp(command,"show",4)==0 | strncmp(command, "menu",4)==0 | strncmp(command,"status",6)==0 ) { strcpy(command,"xxx"); relay_read(iomodule,iabcd,&jdata) ; printf(" jdata= %x \n", jdata); if ( strncmp(aew,"East",4)==0){ jdata = jdata >> 15-1; } else if ( strncmp(aew,"West",4)==0){ jdata = jdata >> 5-1; } else { printf("/n *** This should never happen ***\n\n"); } printf(" +----------------------------------------------+ | COMMANDS: status: | | ----------------------------------------- |"); printf(" | east / west %4s |",aew); printf(" | reset |"); if ((jdata & ch1_on) == 0){ strcpy(astat,"auto");} else { strcpy(astat," on ");} printf(" | chiller1 on/auto %5s |",astat); if ((jdata & ch2_on) == 0){ strcpy(astat,"auto");} else { strcpy(astat," on ");} printf(" | 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(" | 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(" | 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(" | lv on/off/auto %5s |",astat); printf(" | show, status, help, menu: show status | | exit, quit, x, q: exit the program | +----------------------------------------------+ "); } else if ( strncmp(command,"east",4)==0) { ipin = 15; /* For the pin mapping: (see above) */ iew = 0; strcpy(aew , "East"); printf(" Switching to %s controls \n",aew); strcpy(command,"show"); } else if ( strncmp(command,"west",4)==0) { ipin = 5; iew = 1; strcpy(aew , "West"); printf(" Switching to %s controls \n", aew); strcpy(command,"show"); } /* http://p25ext.lanl.gov/phenix/mvd/ */ else if ( strncmp(command,"reset",5)==0 ) { sscanf(command,"%s %s",atmp,aonoff); 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]); strcpy(command,"show"); } else if ( strncmp(command,"chiller1",8)==0 ) { sscanf(command,"%s %s",atmp,aonoff); if ( strncmp(aonoff,"on",2)==0 ) { printf("%s chiller 1 forced on \n", aew); printf(" 1 idata[iew] %x \n", idata[iew]); idata[iew] = idata[iew] | ch1_on; printf(" 2 idata[iew] %x \n", idata[iew]); relay_write(iomodule,iabcd,ipin,idata[iew]); } else if ( strncmp(aonoff,"off",3)==0 ) { printf("%s chillers can only be forced on, or set on auto \n", aew); } else if ( strncmp(aonoff,"auto",4)==0 ) { printf("%s chiller 1 going to automatic \n", aew); printf(" 3 idata[iew] %x \n", idata[iew]); idata[iew] = idata[iew] & ~ch1_on; printf(" 4 idata[iew] %x \n", idata[iew]); relay_write(iomodule,iabcd,ipin,idata[iew]); } else { printf(" try 'chiller1 on' or 'chiller1 auto'\n"); } strcpy(command,"show"); } else if ( strncmp(command,"chiller2",8)==0 ) { sscanf(command,"%s %s",atmp,aonoff); if ( strncmp(aonoff,"on",2)==0 ) { printf("%s chiller 2 forced on \n", aew); idata[iew] = idata[iew] | ch2_on; relay_write(iomodule,iabcd,ipin,idata[iew]); } else if ( strncmp(aonoff,"off",3)==0 ) { printf("%s chillers can only be forced on, or set on auto \n", aew); } else if ( strncmp(aonoff,"auto",4)==0 ) { printf("%s chiller 2 going to automatic \n", aew); idata[iew] = idata[iew] & ~ch2_on; relay_write(iomodule,iabcd,ipin,idata[iew]); } else { printf(" try 'chiller2 on' or 'chiller2 auto'\n"); } strcpy(command,"show"); } else if ( strncmp(command,"fan",3)==0) { sscanf(command,"%s %s",atmp,aonoff); if ( strncmp(aonoff,"on",2)==0 ) { 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 ( strncmp(aonoff,"off",3)==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 ( strncmp(aonoff,"auto",4)==0 ) { 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 { printf(" try 'fan on' or 'fan off' \n"); } strcpy(command,"show"); } else if ( strncmp(command,"pump",4)==0) { sscanf(command,"%s %s",atmp,aonoff); if ( strncmp(aonoff,"on",2)==0 ) { 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 ( strncmp(aonoff,"off",3)==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 ( strncmp(aonoff,"auto",4)==0 ) { 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]); } strcpy(command,"show"); } else if ( strncmp(command,"lv",2)==0) { sscanf(command,"%s %s",atmp,aonoff); if ( strncmp(aonoff,"on",2)==0 ) { 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 ( strncmp(aonoff,"off",3)==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 ( strncmp(aonoff,"auto",4)==0 ) { 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 { printf(" try 'lv on' or 'lv off' \n"); } strcpy(command,"show"); } else if ( strncmp(command,"exit",4)==0 | strncmp(command,"x",1)==0 | strncmp(command,"quit",4)==0 | strncmp(command,"q",1)==0 ) { go_on=0; } else { printf("\n Wrong command - to see menu, type help.\n"); } if (go_on == 1) { printf("\n MVD RELAY>>"); if(!strstr(command,"show")) gets(command); } } /* end command loop */ printf(" done \n"); 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 */ printf(" 1: readback %8x \n", readback); 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]; printf(" 2: swapped %8x \n", readback); /* 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 */ printf(" 3: 10b mask %8x \n", readback); printf(" 4: data %8x \n", data); data = data & 0x00000003ff; /* only 10 bits, mask rest */ data = data << (ipin-1); /* shift to ipin */ printf(" 4: msk+shft %8x \n", data); data = data | readback; /* combine old and new */ printf(" 5: data+rdb %8x \n", data); /* 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 */ printf(" 6: reswap'd %8x \n", data); *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 */ /*============================================================================*/