/************************************************************************************ * smHostListToSlave.c * * synopsis: This state machine does the handshake with a slave DSP while the slave * executes a primitive list. * * in this file: initHostListToSlaveSM, smHostListToSlave, slvHostListIdle, * initiateSlvList, initiateSlvPause, initiateSlvResume, * initiateSlvAbort, abortSlvListSMs * * Damon Fasching fasching@wisconsin.cern.ch ************************************************************************************/ #include "resources.h" #include "rodConfiguration.h" #include "memoryPartitions.h" #include "comRegDfns.h" #pragma CODE_SECTION(initHostListToSlaveSM, "xcode"); #pragma CODE_SECTION(smHostListToSlave, "xcode"); #pragma CODE_SECTION(slvHostListIdle, "xcode"); #pragma CODE_SECTION(initiateSlvList, "xcode"); #pragma CODE_SECTION(initiateSlvPause, "xcode"); #pragma CODE_SECTION(initiateSlvResume, "xcode"); #pragma CODE_SECTION(initiateSlvAbort, "xcode"); #pragma CODE_SECTION(abortSlvListSMs, "xcode"); /* state machine states */ #define SLV_IDLE 0 #define SLV_EXECUTING 1 #define SLV_PAUSED 2 /* file level variables */ UINT32 hostListToSlaveState[N_SDSP], startSlvList[N_SDSP], pauseSlvList[N_SDSP], resumeSlvList[N_SDSP], abortSlvList[N_SDSP], pausedMasterList[N_SDSP], getSlvReply[N_SDSP], masterAttending[N_SDSP]; /************************************************************************************ * initHostListToSlaveSM * * synopsis: Initializes the state vector for smHostListToSlave to SLV_IDLE for each * slave DSP. * * NOTE: The caller is responsible to make sure the the slave number is valid. The * code is protected to avoid a segmentation fault. The symptom of an illegal * slave number is that the slave will not be configured. ************************************************************************************/ void initHostListToSlaveSM(UINT32 slvDspNum) { if (slvDspNum < N_SDSP) { hostListToSlaveState[slvDspNum]= SLV_IDLE; startSlvList[slvDspNum]= 0; pauseSlvList[slvDspNum]= 0; resumeSlvList[slvDspNum]= 0; abortSlvList[slvDspNum]= 0; pausedMasterList[slvDspNum]= 0; getSlvReply[slvDspNum]= 0; masterAttending[slvDspNum]= 0; } return; } /************************************************************************************ * smHostListToSlave.c * * synopsis: This function does the handshake with a slave DSP while the slave * executes a primitive list. * * arguments: * IN: slvDspNum - number of the slave DSP being monitored ************************************************************************************/ INT32 smHostListToSlave(UINT32 slvDspNum) { INT32 returnCode = SUCCESS; switch (hostListToSlaveState[slvDspNum]) { /* * SLV_IDLE: The specified slave is on and configured, but not executing a list. */ case SLV_IDLE: /* If instructed via a primitive from the host, inform the slave that there is * a list to execute and go to state which monitors slave list execution. */ if (startSlvList[slvDspNum]) { rstSlvPause(slvDspNum); rstSlvAbort(slvDspNum); setSlvInListRdy(slvDspNum); startSlvList[slvDspNum] = 0; hostListToSlaveState[slvDspNum] = SLV_EXECUTING; } else { RST_RBIT(STATUS_REG_2, SR_HLTS(slvDspNum)); } break; /* * SLV_EXECUTING: The specified slave is executing a primitive list. */ case SLV_EXECUTING: /* Check if the slave has finished list. If so finish the handshake. */ if (getSlvAck(slvDspNum) != 0) { if (pausedMasterList[slvDspNum]) { rstPausedBySlave(); pausedMasterList[slvDspNum] = 0; } if (getSlvReply[slvDspNum]) { if (getSlvOutListRdy(slvDspNum)) { copySlvReply(slvDspNum); } if (masterAttending[slvDspNum]) { decAttendSlvReply(); masterAttending[slvDspNum] = 0; } getSlvReply[slvDspNum] = 0; } rstSlvInListRdy(slvDspNum); hostListToSlaveState[slvDspNum] = SLV_IDLE; } /* If not, check if slave is paused. */ else if (getSlvPaused(slvDspNum) == 1) { hostListToSlaveState[slvDspNum] = SLV_PAUSED; } /* If requested by host, instruct slave to pause or abort list execution. */ if (pauseSlvList[slvDspNum]) { setSlvPause(slvDspNum); pauseSlvList[slvDspNum] = 0; } if (abortSlvList[slvDspNum]) { setSlvAbort(slvDspNum); abortSlvList[slvDspNum] = 0; } break; /* * SLV_PAUSED: List execution on the specified slave is currently paused. */ case SLV_PAUSED: /* If requested by host, instruct slave to resume or abort list execution. */ if (resumeSlvList[slvDspNum]) { rstSlvPause(slvDspNum); toggleSlvResume(slvDspNum); hostListToSlaveState[slvDspNum] = SLV_EXECUTING; resumeSlvList[slvDspNum] = 0; } if (abortSlvList[slvDspNum]) { setSlvAbort(slvDspNum); hostListToSlaveState[slvDspNum] = SLV_EXECUTING; abortSlvList[slvDspNum] = 0; } break; } return returnCode; } /************************************************************************************ * slvHostListIdle => synopsis: Returns 1/0 if the state machine is idle/notIdle ************************************************************************************/ UINT32 slvHostListIdle(UINT32 slvDspNum) { return (hostListToSlaveState[slvDspNum] == (SLV_IDLE)); } /************************************************************************************ * The following functions set flags which drive the state machine. They are * executed when the DSP receives the appropriate primitive. ************************************************************************************/ void initiateSlvList(UINT32 slvDspNum, UINT32 pauseMasterList, UINT32 getSlaveReply) { SET_RBIT(STATUS_REG_2, SR_HLTS(slvDspNum)); startSlvList[slvDspNum] = 1; if (pauseMasterList) { setPausedBySlave(); pausedMasterList[slvDspNum] = 1; } if (getSlaveReply) { getSlvReply[slvDspNum] = 1; if (getReplyDest(slvDspNum) == ((UINT32 *)DEFAULT)) { incAttendSlvReply(); masterAttending[slvDspNum] = 1; } } return; } /* --------------- */ void initiateSlvPause(UINT32 slvDspNum) { pauseSlvList[slvDspNum] = 1; return; } /* --------------- */ void initiateSlvResume(UINT32 slvDspNum) { resumeSlvList[slvDspNum] = 1; return; } /* --------------- */ void initiateSlvAbort(UINT32 slvDspNum) { abortSlvList[slvDspNum] = 1; return; } /************************************************************************************ * abortSlvListSMs: Aborts any slave list which was started by a master list which * has been aborted. ************************************************************************************/ void abortSlvListSMs(void) { UINT32 slvDspIdx; for (slvDspIdx = 0; slvDspIdx < N_SDSP; ++slvDspIdx) { if (hostListToSlaveState[slvDspIdx] == SLV_EXECUTING || hostListToSlaveState[slvDspIdx] == SLV_PAUSED) { initiateSlvAbort(slvDspIdx); } } }