/************************************************************************************ * slaveTasks.c * * synopsis: This file contains tasks which run on the slave DSPs. Typically these * tasks process event data as it arrives. * * in this file: histogramTask, trapTask, errorTask, occupancyTask, resynchTask * * related files: * taskManager.c: Contains routines for starting, stopping & managing tasks. * masterTasks.c: Contains the master DSP tasks. * histogram.h: Contains the definitions for the histogram control structures * on the master & slave DSPs. ************************************************************************************/ #include #include #include #include #include "resources.h" #include "memoryPartitions.h" #include "taskManager.h" #include "rodConfiguration.h" #include "comRegDfns.h" #include "histogram.h" extern char genStr[]; extern TIMER_Handle timer1; /* general purpose timer, started in main() */ extern far HistoCtrl histoCtrl; extern far BinCtr binCtr; #pragma CODE_SECTION(histogramTask, "icode"); #pragma CODE_SECTION(trapTask, "icode"); #pragma CODE_SECTION(occupancyTask, "xcode"); #pragma CODE_SECTION(errorTask, "xcode"); #pragma CODE_SECTION(resynchTask, "xcode"); /* Histogram Task state-machine states: */ /* TASK_INIT == 1 */ #define HISTO_READY 0x2 #define HISTO_EXPECTING 0x3 #define HISTO_LOCAL_INC 0x4 #define HISTO_LOCAL_TRIG 0x5 #include #include typedef struct { UINT32 code, loopCnt, timeStamp, procTime; UINT32 trapStat[3], isrState; UINT32 nEvents, nHistoEvents, p4MaskStat, maskFlag; } GenEventInfo; GenEventInfo *genEventInfo= (GenEventInfo *) 0xb0000000; /************************************************************************************ * histogramTask * * synopsis: histogramming task. * * author: Douglas Ferguson #define R_HISTOGRAM_TASK 100 struct HISTOGRAM_TASK_IN { UINT32 nEvents, controlFlag; * nEvents can equal COLLECT_FOREVER too. }; #define MASTER_HREG 0 #define LOCAL_INC 1 #define LOCAL_SET_TRIG 2 struct HISTOGRAM_TASK_OUT { UINT32 nEvents, binsDone; FLOAT32 avgProcTime; UINT32 *dataPtr, dataLength; }; ************************************************************************************/ INT32 histogramTask(TaskInput *tsi, TaskOutput *tso, UINT32 opFlags) { static INT32 returnCode, errorCode; static UINT8 state= TASK_INIT, controlFlag, first, set; static UINT32 nEvents, nEventsBin, nTotBin, nErrorsBin, nErrorMask, idleCnt; static FLOAT32 avgProcTime; static UINT16 binsDone, bin; struct EventData *data; UINT32 procTime, t0= 0, t1= 0, t3= 0; UINT32 val; /********************* data retrieval & routine reset *********************/ if (opFlags > 0x10) { /* Place the interesting internal variables into the output structure */ tso->histogramTaskOut.nEvents= nEvents; tso->histogramTaskOut.binsDone= binsDone; tso->histogramTaskOut.avgProcTime= avgProcTime; tso->histogramTaskOut.dataPtr= histoCtrl.base; tso->histogramTaskOut.dataLength= histoCtrl.size; if (opFlags & TASK_HALT_MASK) { newInformation(__FILE__, __LINE__, "Histogram task halting.\n"); state= TASK_INIT; return TASK_HALTED; } else if (opFlags & TASK_INIT_MASK) { newInformation(__FILE__, __LINE__, "Histogram task re-initing.\n"); state= TASK_INIT; return TASK_INITIALIZED; } else if (opFlags & TASK_QUERY_MASK) { newInformation(__FILE__, __LINE__, "Histogram task query data output.\n"); return TASK_QUERIED; } } /*************************** routine states:INIT **************************/ if (state == TASK_INIT) { /* set up any static variables beyond state */ if (GET_RBIT(DIAGNOSTIC_REG, DR_INFO_DISPLAY)) { newInformation(__FILE__, __LINE__, "state -> INIT \n\n."); } returnCode= REPEAT_TASK; nEvents= 0; binsDone= 0; first= TRUE; avgProcTime= 0.00; nEventsBin= nErrorsBin= nTotBin= 0; controlFlag= tsi->histogramTaskIn.controlFlag; if (!histoCtrl.histogramsAreSetup) { /* return error */ sprintf(genStr, "%s%s","Histograms have not been defined yet. ", "Run histogramSetup primitive and re-start.\n\n"); newError(&returnCode, NO_HISTOGRAMS_ERROR, FATAL_ERR, "histogramTask", genStr, __FILE__, __LINE__); return returnCode; } set= histoCtrl.histogramSet; bin= histoCtrl.currentBin; tso->histogramTaskOut.nEvents= nEvents; tso->histogramTaskOut.binsDone= binsDone; tso->histogramTaskOut.avgProcTime= avgProcTime; tso->histogramTaskOut.dataPtr= histoCtrl.base; tso->histogramTaskOut.dataLength= histoCtrl.size; nErrorMask= READ_REG(RESERVED_REG_0); if (controlFlag == MASTER_HREG) { SET_RBIT(HSTAT_REG_0, HSR0_SLV_RDY); state= HISTO_READY; } else if (controlFlag == LOCAL_INC) { state= HISTO_LOCAL_INC; /* ASGN_RFLD(HSTAT_REG_0,HSR0_SLV_SET,HSR0_SLV_SET_W,set); */ ASGN_RFLD(HCMD_STAT_REG_0, HCSR0_SLV_BIN, HCSR0_SLV_BIN_W, bin); } else if (controlFlag == LOCAL_SET_TRIG) { state= HISTO_LOCAL_TRIG; } setTaskState(HISTOGRAM_TASK, state); } /************************* routine states:LOCAL_TRIG **********************/ if (state == HISTO_LOCAL_TRIG) { if (first) { first= FALSE; newInformation(__FILE__, __LINE__, "state -> LOCAL_TRIG \n\n."); setTaskState(HISTOGRAM_TASK, state); } /* bin & set are set by a locally running setTrigger, need only update the variables. */ set= histoCtrl.histogramSet; bin= histoCtrl.currentBin; /* ASGN_RFLD(HSTAT_REG_0,HSR0_SLV_SET,HSR0_SLV_SET_W,set); */ ASGN_RFLD(HCMD_STAT_REG_0, HCSR0_SLV_BIN, HCSR0_SLV_BIN_W, bin); } /***************************** Event Processing ***************************/ data= getNextEvent(); if (data != NULL) { //If an event is ready, update the idle counter in the status register: WRITE_REG(HSTAT_REG_2, idleCnt); idleCnt= 0; if (state == HISTO_READY) { if (!(data->flags & OBSERVATION_STRAY_MASK)) { data->flags |= OBSERVATION_STRAY_MASK; sprintf(genStr, "%s%s%s%s%d%s", "An unexpected event arrived without ", "the Master DSP indicating that it was sending ", "triggers. Event marked as a stray event. Internal ", "ID= ",data->id,".\n"); newError(&errorCode, UNEXPECTED_EVENT, ERROR_0, "histogramTask", genStr, __FILE__, __LINE__); } eventInfo0M; } /* if errors, print warning message and leave event as a marked stray; the event manager will then copy it to the reserve buffer for observation. */ else if (data->error > 0) { if (!(data->flags & OBSERVATION_STRAY_MASK)) { data->flags |= OBSERVATION_STRAY_MASK; //if (data->nErrors != nErrorMask) { sprintf(genStr, "%s", "Event contains errors; marked as a stray event.\n"); newError(&errorCode, HISTOGRAMMING_ERROR_EVT, ERROR_0, "histogramTask", genStr, __FILE__, __LINE__); //} ++nErrorsBin; ASGN_RFLD(HSTAT_REG_0, HSR0_SLV_BINERR, HSR0_SLV_BINERR_W, nErrorsBin); } eventInfo1M; } else { /* for all other states, process the event */ #if 0 /* informational histogramming fxn */ //if (GET_RBIT(DIAGNOSTIC_REG, DR_DISP_LINK_DATA)) histoEvent_list(data); /* non- optimized histogramming fxn */ t1= 0; if (GET_RBIT(DIAGNOSTIC_REG, DR_HISTO_1)) { fsrp0_on; t0= TIMER_getCount(timer1); //histoEvent1(data); t1= (delta_t(t0))/10; fsrp0_off; } delay(1); #endif fsrp0_on; ++nEventsBin; ++nEvents, ++binCtr.ctr[bin]; SET_RBIT(HSTAT_REG_0, HSR0_SLV_PROC); fsrp0_off; t0= TIMER_getCount(timer1); fsrp0_on; eventInfo2M; histoCtrl.histoFxn(data); fsrp0_off; fsxp0_toggle; procTime= delta_t(t0); fsxp0_toggle; eventInfo3M; delay(1); fsrp0_on; WRITE_REG(HSTAT_REG_1, nEventsBin); WRITE_REG(HSTAT_REG_3, procTime); RST_RBIT(HSTAT_REG_0, HSR0_SLV_PROC); fsrp0_off; if (GET_RBIT(DIAGNOSTIC_REG, DR_INFO_DISPLAY)) { sprintf(genStr, "%s%d%s %s%d%s %s0x%04x%s %s%d, %d and %d%s", "Bin ", bin, ", ", "event ", nEventsBin, ": ", "length (w) ", data->length, ", ", "histo 1 2 3 dt= ", t1, procTime, t3, " micro-seconds.\n"); newInformation(__FILE__, __LINE__, genStr); } } fsrp0_on; /* remove the event from the queue */ //processEvent(data, Q_HISTOGRAM); fsrp0_off; } //If no event, update the idle counter (written to status reg. upon event): else {++idleCnt; } /*************************** routine states:READY *************************/ if (state == HISTO_READY) { if (first) { first= FALSE; if (GET_RBIT(DIAGNOSTIC_REG, DR_INFO_DISPLAY)) { newInformation(__FILE__, __LINE__, "state -> READY \n\n."); } setTaskState(HISTOGRAM_TASK, state); nEventsBin= nErrorsBin= 0; /* WRITE_REG(HSTAT_REG_1, 0); */ } /* check HCMD_STAT_REG_0. If the new-bin bit is set, prepare for receiving events (state -> EXPECTING). */ if (GET_RBIT(HCMD_STAT_REG_0, HCSR0_SLV_NEWBIN)) { bin= GET_RFLD(HCMD_STAT_REG_0, HCSR0_SLV_BIN, HCSR0_SLV_BIN_W); nTotBin= READ_REG(HCMD_STAT_REG_1); /* set= GET_RFLD(HCMD_STAT_REG_0, HCMD_SLV_SET, HCMD_SLV_SET_W); */ set= 0; histoCtrl.currentBin= bin; histoCtrl.histogramSet= set; histoCtrl.calLineEnable= GET_RBIT(HCMD_STAT_REG_0, HCSR0_SLV_CALLINE_EN); if (histoCtrl.calLineEnable) { histoCtrl.calLine= GET_RFLD(HCMD_STAT_REG_0, HCSR0_SLV_CALLINE, HCSR0_SLV_CALLINE_W); } setHistoModuleBase(FALSE /* init */, bin); WRITE_REG(HSTAT_REG_1, nEventsBin); RST_RBIT(HSTAT_REG_0, HSR0_SLV_DONE); SET_RBIT(HSTAT_REG_0, HSR0_SLV_EXP); first= TRUE; state= HISTO_EXPECTING; } } /************************* routine states:EXPECTING ***********************/ else if (state == HISTO_EXPECTING) { fsrp0_on; if (first) { if (GET_RBIT(DIAGNOSTIC_REG, DR_INFO_DISPLAY)) { newInformation(__FILE__, __LINE__, "state -> EXPECTING \n\n."); } first= FALSE; setTaskState(HISTOGRAM_TASK, state); } /* check to see if we have gotten all the expected events for this bin. */ if (nEventsBin >= nTotBin) { RST_RBIT(HSTAT_REG_0, HSR0_SLV_EXP); SET_RBIT(HSTAT_REG_0, HSR0_SLV_DONE); /* WRITE_REG(HCMD_STAT_REG_1, 0); */ if (GET_RBIT(DIAGNOSTIC_REG, DR_INFO_DISPLAY)) { sprintf(genStr, "%s%d%s%d%s%d%s", "Bin #", bin, ": nEvents, nErrors= ", nEventsBin, ", ",nErrorsBin, ".\n"); newInformation(__FILE__, __LINE__, genStr); } first= TRUE; state= HISTO_READY; } fsrp0_off; } /************************* routine states:LOCAL_INC ***********************/ else if (state == HISTO_LOCAL_INC) { if (first) { first= FALSE; newInformation(__FILE__, __LINE__, "state -> LOCAL_INC \n\n."); setTaskState(HISTOGRAM_TASK, state); } if (data != NULL) { ++bin; bin%= histoCtrl.nBins; histoCtrl.currentBin= bin; setHistoModuleBase(FALSE /* init */, bin); ASGN_RFLD(HCMD_STAT_REG_0, HCSR0_SLV_BIN, HCSR0_SLV_BIN_W, bin); } } /**************************************************************************/ if (tsi->histogramTaskIn.nEvents != COLLECT_FOREVER) { if (nEvents >= tsi->histogramTaskIn.nEvents) { state= TASK_DONE; setTaskState(HISTOGRAM_TASK, state); return SUCCESS; /* task removal will gather output information */ } } fsrp0_on; delay(5); fsrp0_off; return returnCode; } #pragma DATA_SECTION(trapTempOut, "idata"); struct tTO { UINT32 marker; UINT32 tFlag; UINT32 nTrapped; UINT32 nTot; } trapTempOut; #define TRAP_REQUEST 0x2 #define TRAP_EVENTS 0x3 /************************************************************************************ * trapTask * * synopsis: Traps incoming events (places them in the appropriate spot in memory), * and exits when the requested number of events have been collected. * It is the responsibility of the user to make sure that the events are * transferred (sp?) out of memory in a timely manner, to prevent the trapping * buffer from over-filling. The (nyi) master event trap monitoring routine helps * to coordinate this effort; for now everything is manual. * * input parameters: * * nEvents: The number of events to trap. If the special COLLECT_FOREVER value * is input (the same as in eventTrapSetup), events will be sought * until the task is ended. If HOST_TRIGGERED_EVENTS is input, the master DSP * will watch the trap command register for requests from the VME host. (This * is functionally equivalent to, but more convenient and efficient than, * sending a series of 1 event trapping tasks using startTask; it also frees the * master DSPs primitive list for other priorities). * * reloadInterval: The interval in task iterations before a trap request is sent * to the master event trap monitoring routine, once an event has * been trapped. If zero, the trap is put in continuous mode until at least the * number of requested events have been gathered; otherwise the trap is set for * single-shot collecting and the trap reset according to the reload interval. * * trapType: The type of events to be captured: ATLAS, TIM, ROD or ERROR events. * (The same parameters as used for eventTrapSetup). The trapping * task is meant to be run as an auxiliary task, started when necessary & then * running alongside other pre-existing tasks. Therefore the preferred way of * setting the parameters in eventTrapSetup is to leave the 2nd trap idle, and * input the needed parameters here. If both traps have already been set by the * ets primitive, the trap configuration input here must be idle, and at least * one of the two traps must be pre-configured to send events to the trapping * task. * * eventType: The type of ATLAS, TIM or ROD events desired. * * recycle (nyi): If set, the task recycles events after it has filled its buffer; * meant to be used in conjunction with the master monitoring * routine, which will relay data locations to the host. * * trapAttempts (pi): The number of attempts the task will make to trap the * event before discarding it. This can be shorter than the * event manager iteration limit; if it is longer the event will be treated as * a stray event. * * trapBufferBase, trapBufferLength: The location & length of memory to use as a * trapping buffer; defaults are supplied. It is * the user's responsibility to avoid over-writing other critical data; later * when a more useful form of memory allocation is done this can be tested for. * * override (nyi): For later use. * * author: Douglas Ferguson ************************************************************************************/ INT32 trapTask(TaskInput *tsi, TaskOutput *tso, UINT32 opFlags) { static INT32 returnCode; static UINT8 state= TASK_INIT, first; static UINT32 compLen; static UINT32 *bufferBase, bufferLen, nEvents, eventType, eventAnalysis; /*iteration= 0, lastRequestIter= 0, trapAttempts= 0; */ static UINT32 dataLen, nEventsTrapped, eventCount; struct EventData *data; INT32 errorCode; UINT32 nErrors, routerError, *dataPtr1, *dataPtr2, i; UINT8 trapEvent; /********************* data retrieval & routine reset *********************/ if (opFlags > 0x10) { /* Place the interesting internal variables into the output structure */ tso->trapTaskOut.nEvents= nEventsTrapped; tso->trapTaskOut.dataLen= dataLen; tso->trapTaskOut.bufferBase= bufferBase; tso->trapTaskOut.bufferLen= bufferLen; if (opFlags & TASK_HALT_MASK) { newInformation(__FILE__, __LINE__, "Trap task halting.\n"); state= TASK_INIT; return TASK_HALTED; } else if (opFlags & TASK_INIT_MASK) { newInformation(__FILE__, __LINE__, "Trap task re-initing.\n"); state= TASK_INIT; return TASK_INITIALIZED; } else if (opFlags & TASK_QUERY_MASK) { newInformation(__FILE__, __LINE__, "Trap task query data output.\n"); return TASK_QUERIED; } } /*************************** routine states:INIT **************************/ if (state == TASK_INIT) { /* set up any static variables beyond state */ newInformation(__FILE__, __LINE__, "state -> INIT \n\n."); returnCode= REPEAT_TASK; first= TRUE; dataLen= nEventsTrapped= eventCount= 0; nEvents= tsi->trapTaskIn.nEvents; eventType= tsi->trapTaskIn.eventType; bufferBase= tsi->trapTaskIn.trapBufferBase; bufferLen= tsi->trapTaskIn.trapBufferLength; trapTempOut.marker= 0xdfdfdfdf; trapTempOut.tFlag= eventType & (1<<30); eventAnalysis= eventType & (1<<31); if (eventAnalysis) { ++nEventsTrapped; dataPtr1= dataPtr2= bufferBase -0xa00; compLen= 0; while ((dataPtr25)&&(iteration <= 10)) { /* simulate delay */ init= 0; /*if no reply: return returnCode; else : init= 0, make 1st request & set lastRequestIter */ } else if (iteration> 10) { /* error message & exit w/error */ return -1; } } if (init) return returnCode; #endif if (state == TRAP_EVENTS) { if (first) { first= FALSE; newInformation(__FILE__, __LINE__, "state -> TRAP_EVENTS \n\n."); setTaskState(TRAP_TASK, state); } if ((data= getNextEvent())!= NULL) { ++eventCount; /* //nErrors= data->nErrors; routerError= data->routerError; trapEvent= ( ((eventType & 1)&&((nErrors>0)||(routerError>0))) ||((eventType & 2)&&((nErrors==0)&&(routerError==0))) ); */ trapEvent= TRUE; /* te1= (eventType & 1); te2= (eventType & 2); te3= ((nErrors>0)||(routerError>0)); te4= ((nErrors==0)&&(routerError==0)); sprintf(genStr, "%s %d %d %d %d %d %d %d %d %s", "eventType, te1, te2, nErrors, routerError, trapEvent, te3, te4: ", eventType, te1, te2, nErrors, routerError, trapEvent, te3, te4, ".\n"); newInformation(__FILE__, __LINE__, genStr); */ if (eventAnalysis) { /* primitive compare: will work for 1 frame & any events which do not cause a buffer overflow or wrap in the middle of the event. */ dataPtr1= bufferBase -0xa00; dataPtr2= (UINT32 *) getFramePtr(data->startFrame); for (i=0; ilength <= (bufferLen -dataLen)) { if (trapEvent) { /* start= (UINT32 *) getFramePtr(data->startFrame); start+= 4; *start= eventCount; */ fsrp0_on; if (trapTempOut.tFlag) copyEvent(data, bufferBase +dataLen); /* copyEvent(data, bufferBase +dataLen); */ fsrp0_off; dataLen+= data->nFrames*0x100; ++nEventsTrapped; /* dataLen+= data->length; ++nEventsTrapped; */ } //processEvent(data, Q_TRAP); /* indicate in status register that event we requested was found.*/ } /* empty trapping buffer and re-fill; send an error message. */ else { if (trapEvent) { sprintf(genStr, "%s%x%s%x%s%x%s", "The event trapping buffer has ", dataLen," words used and ", bufferLen-dataLen," available; \n", /*data->length,*/ data->nFrames*0x100, " is needed to trap the current event. Recycling buffer.\n\n"); newError(&errorCode, MEMORY_EXCEEDED, ERROR_0, "trapTask", genStr, __FILE__, __LINE__); dataLen= 0; if (trapTempOut.tFlag) copyEvent(data, bufferBase +dataLen); /* copyEvent(data, bufferBase +dataLen); */ dataLen+= data->nFrames*0x100; ++nEventsTrapped; } //processEvent(data, Q_TRAP); #ifdef COMMENTED /* else if (tsi->trapTaskIn.recycle) { check if it fits, then remove enough events from buffer to make space for them. Three possible values for flag: TRAP_TASK_NO_RECYCLE -> error TRAP_TASK_RECYCLE_SILENT -> no info message TRAP_TASK_RECYCLE_NOTIFY -> info message once space is available, copy & process event. Re-compute params } */ /* A (generally limited) number of trapping attemts will be made. If the iterLimit parameter of the event manager is smaller than the input attempt maximum and it is reached, the event will be treated as a stray event there and we suddenly will not see it again. Those events may have been sent to the event manager's reserve buffer. */ ++trapAttempts; if (trapAttempts == 1) { sprintf(genStr, "%s%d%s%d%s%d%s", "The event trapping buffer has ", dataLen," words used and ", (tsi->trapTaskIn.trapBufferLength-dataLen)," available; \n", data->length, " is needed to trap the current event. Event not trapped.\n\n"); newError(&errorCode, MEMORY_EXCEEDED, ERROR_0, "trapTask", genStr, __FILE__, __LINE__); } else if (trapAttempts >= 3) { /* dummy input = 3*/ sprintf(genStr, "%s%s%d%s", "The event trapping buffer was ", "still not large enough after ",3, " attempts. Event discarded.\n\n"); newError(&errorCode, EVENT_DISCARDED, ERROR_1, "trapTask", genStr, __FILE__, __LINE__); processEvent(data, Q_TRAP); trapAttempts= 0; } #endif } /* buffer full */ trapTempOut.nTot= eventCount; trapTempOut.nTrapped= nEventsTrapped; } /* event has arrived */ } /* TRAP_EVENTS */ /* if not collecting forever, or via host request: if iteration > lastRequestIter & there is acknowledgement by master of last request, and in turn we have set the status register flag indicating that the event we requested was found, make another request. Otherwise we should wait. */ /**************************************************************************/ if (nEvents != COLLECT_FOREVER) { /* & not recycling */ if (nEventsTrapped >= nEvents) { returnCode= SUCCESS; tso->trapTaskOut.nEvents= nEventsTrapped; tso->trapTaskOut.dataLen= dataLen; tso->trapTaskOut.bufferBase= bufferBase; tso->trapTaskOut.bufferLen= bufferLen; } } /* if (taskMgrCtrlPtr->taskIterations%1000000== 0) newInformation(__FILE__, __LINE__, "Event trapping task running.\n"); */ return returnCode; } /************************************************************************************ * occupancyTask * * synopsis: Occupancy map task. * * author: Douglas Ferguson ************************************************************************************/ INT32 occupancyTask(TaskInput *tsi, TaskOutput *tso, UINT32 opFlags) { static INT32 returnCode; static UINT8 state= TASK_INIT, first; /********************* data retrieval & routine reset *********************/ if (opFlags > 0x10) { /* Place the interesting internal variables into the output structure */ //tso->occupancyTaskOut.nEvents= nEvents; if (opFlags & TASK_HALT_MASK) { newInformation(__FILE__, __LINE__, "Occupancy task halting.\n"); state= TASK_INIT; return TASK_HALTED; } else if (opFlags & TASK_INIT_MASK) { newInformation(__FILE__, __LINE__, "Occupancy task re-initing.\n"); state= TASK_INIT; return TASK_INITIALIZED; } else if (opFlags & TASK_QUERY_MASK) { newInformation(__FILE__, __LINE__, "Occupancy task query data output.\n"); return TASK_QUERIED; } } /*************************** routine states:INIT **************************/ if (state == TASK_INIT) { returnCode= REPEAT_TASK; } /**************************************************************************/ return returnCode; } /************************************************************************************ * errorTask * * synopsis: error counting & processing task. * * author: Douglas Ferguson ************************************************************************************/ INT32 errorTask(TaskInput *tsi, TaskOutput *tso, UINT32 opFlags) { static INT32 returnCode; static UINT8 state= TASK_INIT, first; /********************* data retrieval & routine reset *********************/ if (opFlags > 0x10) { /* Place the interesting internal variables into the output structure */ //tso->occupancyTaskOut.nEvents= nEvents; if (opFlags & TASK_HALT_MASK) { newInformation(__FILE__, __LINE__, "Error task halting.\n"); state= TASK_INIT; return TASK_HALTED; } else if (opFlags & TASK_INIT_MASK) { newInformation(__FILE__, __LINE__, "Error task re-initing.\n"); state= TASK_INIT; return TASK_INITIALIZED; } else if (opFlags & TASK_QUERY_MASK) { newInformation(__FILE__, __LINE__, "Error task query data output.\n"); return TASK_QUERIED; } } /*************************** routine states:INIT **************************/ if (state == TASK_INIT) { returnCode= REPEAT_TASK; } /**************************************************************************/ return returnCode; } /************************************************************************************ * resynchTask * * synopsis: Re-synchronization of events in case of detector electronics glitch. * * author: Douglas Ferguson ************************************************************************************/ INT32 resynchTask(TaskInput *tsi, TaskOutput *tso, UINT32 opFlags) { static INT32 returnCode; static UINT8 state= TASK_INIT, first; /********************* data retrieval & routine reset *********************/ if (opFlags > 0x10) { /* Place the interesting internal variables into the output structure */ //tso->occupancyTaskOut.nEvents= nEvents; if (opFlags & TASK_HALT_MASK) { newInformation(__FILE__, __LINE__, "Resynch task halting.\n"); state= TASK_INIT; return TASK_HALTED; } else if (opFlags & TASK_INIT_MASK) { newInformation(__FILE__, __LINE__, "Resynch task re-initing.\n"); state= TASK_INIT; return TASK_INITIALIZED; } else if (opFlags & TASK_QUERY_MASK) { newInformation(__FILE__, __LINE__, "Resynch task query data output.\n"); return TASK_QUERIED; } } /*************************** routine states:INIT **************************/ if (state == TASK_INIT) { returnCode= REPEAT_TASK; } /**************************************************************************/ return returnCode; }