/* * ce_sub40pec An EPICS subroutine record code module. * * This module will receive events and relative event times from the user, * as well as the current NSTX clock Event Times. * * * If the specified clock event is tzero, or T(-1), * this program will figure out the nearest fixed clock event * and use the fastest clock rate. If the time is prior to T(-60) then * SOC evt will be used. A negative time specified lesser then SOC will be * set to SOC. Because SOP can vary, it is being avoided * when tzero is the reference code. * * If SOP is the chosen code, and the delay is negative, then * T(-60) will be used a the event code with the proper delay * for the present setting of SOP. * * If any other event is chosen the * relative time must be non-negative (neg vals will be forced to zero). * * A special switch is the Power Conversion * Local Test Cycle. If it is active, then the user-specified SOP * and Tzero relative times will be adjusted to use the SOP * value of the pc_localccycle. This way the PC user can use * one digitizer setting for either an NSTX or a LOCAL cycle. * * Neutral Beams has two special codes FBL and NBI. These are the only codes * that will go out on the Facility Clock Link * for both NB conditioning cycles and HPP-synced cycles. The abstime * can be calculated for these two events. * * 16-bit 404 Code value will be placed in psub->l. The 20-bit * delay count and 2-bit delay clock will written to psub->k. The * absolute time (rel to T(0)) will go to psub->val. * The abstime is * valid for relevt's SOC, SOP, T(-1) and T(0). * The abstime is also valid for relevt's FBL and NBI. * The abstime for all of * these six events must be greater than SOC. * * Rev 0 06NOV98 ps Created * Rev 1 18DEC98 ps Set UDF to "0" * Rev 2 10MAY99 ps Added 'case' statements to also use 14*, 15* values. * Rev 3 19SEP00 ps Added fbl and nbi event capability for Neutral Beams. * */ #include #include #include #include #include #include #include #include #define DAS_LEAD -(2.1) /* time prior to SOP that the * DAS speed-switch process is * started. Applies to FCPC Local Cycles. */ #define MAX_1MHZ 1.048575 #define MAX_100KHZ 10.48575 #define MAX_10KHZ 104.8575 #define MAX_1KHZ 1048.575 int delayword(float delaytime); /*prototype the function*/ long ce_404init(psub) struct subRecord *psub; { /* load in defaults */ psub->a = 0; psub->b = 6; /* SOD or T(0) */ psub->c = 0; /* NSTX Clock */ psub->d = 0; psub->e = 0; psub->f = 0; psub->g = 0; /* FBL to NBI delay in ms */ psub->h = 0; /* NBI master delay after T(0) in ms */ psub->k = 0; psub->l = 0x40; /* T(0) */ psub->val = 0; psub->udf = 0; return(0); } long ce_404proc(psub) struct subRecord *psub; { double soctime,soptime,abstime, reltime,alttime,delaytime, fbldelay,nbitime; int relevt,cyclemode,usecode; /* get parms */ soctime = psub->e; /* in seconds rel to T(0) */ soptime = psub->f; fbldelay = psub->g; /* in millisecs */ nbitime = psub->h; /* in millisecs (after T(0) */ /* implicit times are T(-60), T(-1), and T(0) */ relevt = psub->b; /* decimal valu which mimics octal */ /* 140 = estop, 141=SOC, 142=SOS * 143=T(-60), 144=SOP, 145=T(-1) * 146=T(0)/SOD, 147=NBI, 150=T(+D) * 151=EOD, 152=EOP, 153=Link Test * 154=PC_Fault, 155=PC_Event(local cycle) * 156=FBL, 157=404 Test, 0=Asynchronous */ switch(relevt) { /* convert to octal representations (in decimal) */ case 146: case 6: case 0: relevt=146; /* default to T(0) */ break; case 141: case 1: relevt=141; break; case 142: case 2: relevt=142; break; case 143: case 3: relevt=143; break; case 144: case 4: relevt=144; break; case 145: case 5: relevt=145; break; case 147: case 7: relevt=147; break; case 150: case 8: relevt=150; break; case 151: case 9: relevt=151; break; case 152: case 10: relevt=152; break; case 153: case 11: relevt=153; break; case 154: case 12: relevt=154; break; case 155: case 13: relevt=155; break; case 156: case 14: relevt=156; break; case 157: case 15: relevt=157; break; } reltime = psub->a; /* rel time to spec'd event in seconds */ cyclemode = psub->c; /* 0=NSTX cycle, 1 = PC local cycle */ alttime = psub->d; /* set defaults */ delaytime = reltime; usecode = 0x0040; /* default SOD */ abstime = 0; if(cyclemode == 0) { /* NSTX Central Clock Sync Mode */ if(relevt == 146) { abstime = reltime; if(reltime > 0) { usecode = 0x0040; delaytime = reltime; } else if(reltime >= -1) { usecode = 0x0020; delaytime = -(-1 - reltime); } else if(reltime >= -60) { usecode = 0x0008; delaytime = -(-60 - reltime); } else if(reltime >= soctime) { usecode = 0x0002; delaytime = -(soctime - reltime); } else { usecode = 0x0002; delaytime = 0; abstime = soctime; } } else if(relevt == 141) { usecode = 0x0002; if(reltime < 0) { reltime = 0; } delaytime = reltime; abstime = soctime + delaytime; } else if(relevt == 142) { usecode = 0x0004; if(reltime < 0) reltime = 0; delaytime = reltime; } else if(relevt == 143) { usecode = 0x0008; if(reltime < 0) reltime = 0; delaytime = reltime; abstime = -60 + delaytime; } else if(relevt == 144) { /* must support reltime up to -60 */ usecode = 0x0010; if(reltime < 0) { usecode = 0x0008; delaytime = -(-60 - reltime - soptime); if(delaytime < 0) delaytime = 0; abstime = -60 + delaytime; } else { delaytime = reltime; abstime = soptime + delaytime; } } else if(relevt == 145) { usecode = 0x0020; if(reltime < 0) { if (reltime >= -59) { usecode = 0x0008; delaytime = -(-60 - reltime - (-1)); if(delaytime < 0) delaytime = 0; abstime = -60 + delaytime; } else { usecode = 0x0002; delaytime = -(soctime - reltime - (-1)); if(delaytime < 0) delaytime = 0; abstime = soctime + delaytime; } } else { /* positive delay */ delaytime = reltime; abstime = (-1) + reltime; } } else if(relevt == 147) { /* NBI event */ if(reltime >= 0) { usecode = 0x0080; delaytime = reltime; /* time in seconds */ abstime = nbitime/1000 + delaytime; } else if (reltime <= -fbldelay/1000) { /* use FBL with a zero delay. time cannot be less than fbl to nbi time */ usecode = 0x4000; /* use FBL event */ delaytime = 0; abstime = nbitime/1000 - fbldelay/1000; } else { /* use FBL with a delay. */ usecode = 0x4000; /* use FBL event */ delaytime = fbldelay/1000 + reltime; abstime = nbitime/1000 + reltime; } } else if(relevt == 150) { usecode = 0x0100; if(reltime < 0) reltime = 0; delaytime = reltime; } else if(relevt == 151) { usecode = 0x0200; if(reltime < 0) reltime = 0; delaytime = reltime; } else if(relevt == 152) { usecode = 0x0400; if(reltime < 0) reltime = 0; delaytime = reltime; } else if(relevt == 153) { usecode = 0x0800; if(reltime < 0) reltime = 0; delaytime = reltime; } else if(relevt == 154) { usecode = 0x1000; if(reltime < 0) reltime = 0; delaytime = reltime; } else if(relevt == 155) { usecode = 0x2000; if(reltime < 0) reltime = 0; delaytime = reltime; } else if(relevt == 156) { /* FBL event */ usecode = 0x4000; if(reltime < 0) reltime = 0; delaytime = reltime; abstime = nbitime/1000 - fbldelay/1000 + delaytime; } else if(relevt == 157) { usecode = 0x8000; if(reltime < 0) reltime = 0; delaytime = reltime; } else { /* default on unrecognized event code */ usecode = 0x0040; /* T(0) */ delaytime = 0; } } /* special case for FCPC Local Cycle */ /* only sop and sod evts allowed */ if(cyclemode == 1) { usecode = 0x2000; if(relevt==144) { if(reltime < DAS_LEAD) delaytime = 0; else delaytime = -DAS_LEAD + reltime; abstime = (DAS_LEAD + alttime) + delaytime; } else if(relevt==146) { if( reltime < (DAS_LEAD + alttime) ) { delaytime = 0; abstime = (DAS_LEAD + alttime) ; } else { delaytime = -(DAS_LEAD + alttime) + reltime; abstime = reltime; } } else { /* default to start at SOP */ delaytime = -(DAS_LEAD); abstime = alttime; } } psub->k = (int)delayword(delaytime); psub->l = (int)usecode; psub->val = abstime; psub->udf = 0; return(0); } int delayword(float reltime) /* define the function */ { int rtnval; if(reltime <= MAX_1MHZ) rtnval = (int)((reltime * 1E+6) + 0.0000005); else if(reltime <= MAX_100KHZ) rtnval = (int)((reltime * 1E+5) + 0.0000005) | 0x100000; else if(reltime <= MAX_10KHZ) rtnval = (int)((reltime * 1E+4) + 0.0000005)| 0x200000; else { if(reltime <= MAX_1KHZ) rtnval = (int)((reltime * 1E+3) + 0.0000005) | 0x300000; else rtnval = (int)((MAX_1KHZ * 1E+3) + 0.0000005) | 0x300000; /* uppr limit */ } return(rtnval); }