diff --git a/src/epics/util/feCodeGen.pl b/src/epics/util/feCodeGen.pl index 4bff5e06e1249d5ba34266b9ba145f4e7c8f1915..9da08a2fb14696e0468a33264f8355c2415c8b6b 100755 --- a/src/epics/util/feCodeGen.pl +++ b/src/epics/util/feCodeGen.pl @@ -1216,6 +1216,12 @@ print EPICS "OUTVARIABLE FEC\_$dcuId\_CPU_METER_MAX epicsOutput.cpuMeterMax int print OUTH "\tint adcWaitTime;\n"; print EPICS "OUTVARIABLE FEC\_$dcuId\_ADC_WAIT epicsOutput.adcWaitTime int ao 0 field(HOPR,\"$rate\") field(EGU,\"usec\") field(LOPR,\"0\")\n"; +print OUTH "\tint adcWaitMin;\n"; +print EPICS "OUTVARIABLE FEC\_$dcuId\_ADC_WAIT_MIN epicsOutput.adcWaitMin int ao 0 field(HOPR,\"$rate\") field(EGU,\"usec\") field(LOPR,\"0\")\n"; + +print OUTH "\tint adcWaitMax;\n"; +print EPICS "OUTVARIABLE FEC\_$dcuId\_ADC_WAIT_MAX epicsOutput.adcWaitMax int ao 0 field(HOPR,\"$rate\") field(EGU,\"usec\") field(LOPR,\"0\")\n"; + print OUTH "\tint timeErr;\n"; print EPICS "OUTVARIABLE FEC\_$dcuId\_TIME_ERR epicsOutput.timeErr int ao 0\n"; diff --git a/src/fe/controllerIop.c b/src/fe/controllerIop.c index 4c3697ef89a5def15b2ea70ac117dd1772782eac..e4554ac35ed5193873ff660fbc851e92fdda37fd 100644 --- a/src/fe/controllerIop.c +++ b/src/fe/controllerIop.c @@ -395,28 +395,11 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo; iopDacEnable = feCode(cycleNum,dWord,dacOut,dspPtr[0],&dspCoeff[0], (struct CDS_EPICS *)pLocalEpics,1); // Initialize timing info variables - timeinfo.cpuTimeEverMax = 0; - timeinfo.cpuTimeEverMaxWhen = 0; - timeinfo.startGpsTime = 0; - timeinfo.usrHoldTime = 0; - timeinfo.timeHold = 0; - timeinfo.timeHoldHold = 0; - timeinfo.timeHoldWhen = 0; - timeinfo.timeHoldWhenHold = 0; - timeinfo.usrTime = 0; - timeinfo.cycleTime = 0; + initializeTimingDiags(&timeinfo); missedCycle = 0; // Initialize duotone measurement signals - for(ii=0;ii<IOP_IO_RATE;ii++) { - dt_diag.adc[ii] = 0; - dt_diag.dac[ii] = 0; - } - dt_diag.totalAdc = 0.0; - dt_diag.totalDac = 0.0; - dt_diag.meanAdc = 0.0; - dt_diag.meanDac = 0.0; - dt_diag.dacDuoEnable = 0.0; + initializeDuotoneDiags(&dt_diag); /// \> Initialize the ADC modules ************************************* pLocalEpics->epicsOutput.fe_status = INIT_ADC_MODS; @@ -720,24 +703,10 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo; // ***************************************************************** if(cycleNum ==HKP_TIMING_UPDATES) { - pLocalEpics->epicsOutput.cpuMeter = timeinfo.timeHold; - pLocalEpics->epicsOutput.cpuMeterMax = timeinfo.timeHoldMax; + sendTimingDiags2Epics(pLocalEpics, &timeinfo, &adcinfo); + pLocalEpics->epicsOutput.dacEnable = dacEnable; - timeinfo.timeHoldHold = timeinfo.timeHold; - timeinfo.timeHold = 0; - timeinfo.timeHoldWhenHold = timeinfo.timeHoldWhen; - - if (timeSec % 4 == 0) pLocalEpics->epicsOutput.adcWaitTime = - adcinfo.adcHoldTimeMin; - else if (timeSec % 4 == 1) - pLocalEpics->epicsOutput.adcWaitTime = adcinfo.adcHoldTimeMax; - else - pLocalEpics->epicsOutput.adcWaitTime = adcinfo.adcHoldTimeAvg/CYCLE_PER_SECOND; - - adcinfo.adcHoldTimeAvgPerSec = adcinfo.adcHoldTimeAvg/CYCLE_PER_SECOND; - adcinfo.adcHoldTimeMax = 0; - adcinfo.adcHoldTimeMin = 0xffff; - adcinfo.adcHoldTimeAvg = 0; + if((adcinfo.adcHoldTime > CYCLE_TIME_ALRM_HI) || (adcinfo.adcHoldTime < CYCLE_TIME_ALRM_LO)) { diagWord |= FE_ADC_HOLD_ERR; @@ -755,11 +724,9 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo; initialDiagReset = 0; pLocalEpics->epicsInput.diagReset = 0; pLocalEpics->epicsInput.ipcDiagReset = 1; - // pLocalEpics->epicsOutput.diags[1] = 0; timeinfo.timeHoldMax = 0; diagWord = 0; ipcErrBits = 0; - for(jj=0;jj<cdsPciModules.adcCount;jj++) adcinfo.adcRdTimeMax[jj] = 0; } pLocalEpics->epicsOutput.diagWord = diagWord; @@ -852,7 +819,6 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo; /// \> Cycle 19, write updated diag info to EPICS if(cycleNum == HKP_DIAG_UPDATES) { - pLocalEpics->epicsOutput.userTime = timeinfo.usrHoldTime; pLocalEpics->epicsOutput.ipcStat = ipcErrBits; if(ipcErrBits & 0xf) feStatus |= FE_ERROR_IPC; // Create FB status word for return to EPICS @@ -867,7 +833,6 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo; pLocalEpics->epicsOutput.fbNetStat = mxStat; mxDiag = mxDiagR; if(mxStat != MX_OK) feStatus |= FE_ERROR_DAQ;; - timeinfo.usrHoldTime = 0; if(pLocalEpics->epicsInput.overflowReset) { if (pLocalEpics->epicsInput.overflowReset) { @@ -1027,31 +992,9 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo; rdtscll(cpuClock[CPU_TIME_CYCLE_END]); /// \> Compute code cycle time diag information. + captureEocTiming(cycleNum, cycle_gps_time, &timeinfo, &adcinfo); timeinfo.cycleTime = (cpuClock[CPU_TIME_CYCLE_END] - cpuClock[CPU_TIME_CYCLE_START])/CPURATE; - // Hold the max cycle time over the last 1 second - if(timeinfo.cycleTime > timeinfo.timeHold) { - timeinfo.timeHold = timeinfo.cycleTime; - timeinfo.timeHoldWhen = cycleNum; - } - // Hold the max cycle time since last diag reset - if(timeinfo.cycleTime > timeinfo.timeHoldMax) timeinfo.timeHoldMax = timeinfo.cycleTime; adcinfo.adcHoldTime = (cpuClock[CPU_TIME_CYCLE_START] - adcinfo.adcTime)/CPURATE; - // Avoid calculating the max hold time for the first few seconds - if (cycleNum != 0 && (timeinfo.startGpsTime+3) < cycle_gps_time) { - if(adcinfo.adcHoldTime > adcinfo.adcHoldTimeMax) - adcinfo.adcHoldTimeMax = adcinfo.adcHoldTime; - if(adcinfo.adcHoldTime < adcinfo.adcHoldTimeMin) - adcinfo.adcHoldTimeMin = adcinfo.adcHoldTime; - adcinfo.adcHoldTimeAvg += adcinfo.adcHoldTime; - if (adcinfo.adcHoldTimeMax > adcinfo.adcHoldTimeEverMax) { - adcinfo.adcHoldTimeEverMax = adcinfo.adcHoldTimeMax; - adcinfo.adcHoldTimeEverMaxWhen = cycle_gps_time; - } - if (timeinfo.timeHoldMax > timeinfo.cpuTimeEverMax) { - timeinfo.cpuTimeEverMax = timeinfo.timeHoldMax; - timeinfo.cpuTimeEverMaxWhen = cycle_gps_time; - } - } adcinfo.adcTime = cpuClock[CPU_TIME_CYCLE_START]; // Calc the max time of one cycle of the user code // For IOP, more interested in time to get thru ADC read code and send to slave apps diff --git a/src/fe/timing.c b/src/fe/timing.c index 4bea37068caf1e2ab9984e69cdc57d2d2ee0d927..de8f7e840d5207c15cacbeeccbed841852f2f3d0 100644 --- a/src/fe/timing.c +++ b/src/fe/timing.c @@ -86,5 +86,82 @@ inline float duotime(int count, float meanVal, float data[]) return(answer); } -#endif +inline void initializeDuotoneDiags(duotone_diag_t *dt_diag) +{ + int ii; + for(ii=0;ii<IOP_IO_RATE;ii++) { + dt_diag->adc[ii] = 0; + dt_diag->dac[ii] = 0; + } + dt_diag->totalAdc = 0.0; + dt_diag->totalDac = 0.0; + dt_diag->meanAdc = 0.0; + dt_diag->meanDac = 0.0; + dt_diag->dacDuoEnable = 0.0; + +} +inline void initializeTimingDiags(timing_diag_t *timeinfo) +{ + timeinfo->cpuTimeEverMax = 0; + timeinfo->cpuTimeEverMaxWhen = 0; + timeinfo->startGpsTime = 0; + timeinfo->usrHoldTime = 0; + timeinfo->timeHold = 0; + timeinfo->timeHoldHold = 0; + timeinfo->timeHoldWhen = 0; + timeinfo->timeHoldWhenHold = 0; + timeinfo->usrTime = 0; + timeinfo->cycleTime = 0; + +} +inline void sendTimingDiags2Epics(CDS_EPICS *pLocalEpics, + timing_diag_t *timeinfo, + adcInfo_t *adcinfo) +{ + pLocalEpics->epicsOutput.cpuMeter = timeinfo->timeHold; + pLocalEpics->epicsOutput.cpuMeterMax = timeinfo->timeHoldMax; + pLocalEpics->epicsOutput.userTime = timeinfo->usrHoldTime; + timeinfo->timeHoldHold = timeinfo->timeHold; + timeinfo->timeHold = 0; + timeinfo->timeHoldWhenHold = timeinfo->timeHoldWhen; + timeinfo->usrHoldTime = 0; + + pLocalEpics->epicsOutput.adcWaitTime = adcinfo->adcHoldTimeAvg/CYCLE_PER_SECOND; + pLocalEpics->epicsOutput.adcWaitMin = adcinfo->adcHoldTimeMin; + pLocalEpics->epicsOutput.adcWaitMax = adcinfo->adcHoldTimeMax; + + adcinfo->adcHoldTimeAvgPerSec = adcinfo->adcHoldTimeAvg/CYCLE_PER_SECOND; + adcinfo->adcHoldTimeMax = 0; + adcinfo->adcHoldTimeMin = 0xffff; + adcinfo->adcHoldTimeAvg = 0; + +} +inline void captureEocTiming(int cycle, unsigned int cycle_gps, timing_diag_t *timeinfo,adcInfo_t *adcinfo) +{ + + // Hold the max cycle time over the last 1 second + if(timeinfo->cycleTime > timeinfo->timeHold) { + timeinfo->timeHold = timeinfo->cycleTime; + timeinfo->timeHoldWhen = cycle; + } + // Hold the max cycle time since last diag reset + if(timeinfo->cycleTime > timeinfo->timeHoldMax) timeinfo->timeHoldMax = timeinfo->cycleTime; + // Avoid calculating the max hold time for the first few seconds + if (cycle != 0 && (timeinfo->startGpsTime+3) < cycle_gps) { + if(adcinfo->adcHoldTime > adcinfo->adcHoldTimeMax) + adcinfo->adcHoldTimeMax = adcinfo->adcHoldTime; + if(adcinfo->adcHoldTime < adcinfo->adcHoldTimeMin) + adcinfo->adcHoldTimeMin = adcinfo->adcHoldTime; + adcinfo->adcHoldTimeAvg += adcinfo->adcHoldTime; + if (adcinfo->adcHoldTimeMax > adcinfo->adcHoldTimeEverMax) { + adcinfo->adcHoldTimeEverMax = adcinfo->adcHoldTimeMax; + adcinfo->adcHoldTimeEverMaxWhen = cycle_gps; + } + if (timeinfo->timeHoldMax > timeinfo->cpuTimeEverMax) { + timeinfo->cpuTimeEverMax = timeinfo->timeHoldMax; + timeinfo->cpuTimeEverMaxWhen = cycle_gps; + } + } +} +#endif