From 8e185c629119a403fa915bd548e2c278fd423417 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Thu, 29 Nov 2012 11:42:44 +1100 Subject: [PATCH] Ferdi's fixes --- multicounter.c | 249 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 164 insertions(+), 85 deletions(-) diff --git a/multicounter.c b/multicounter.c index ed129a69..91e1e09f 100644 --- a/multicounter.c +++ b/multicounter.c @@ -77,9 +77,12 @@ static int MMCCHalt(void *pData) /*-------------------------------------------------------------------------*/ static int MMCCStart(void *pData, SConnection * pCon) { - int i, status; + int i, status, controlMonitor; + int slavePreset, oneYear = 32000000; pCounter pCount = NULL; pMultiCounter self = NULL; + char buffer[128]; + CounterMode slaveMode; pCount = (pCounter) pData; if (pCount != NULL) { @@ -90,12 +93,25 @@ static int MMCCStart(void *pData, SConnection * pCon) if (!GetCountLock(pCount->pCountInt, pCon)) { return HWFault; } + controlMonitor = GetControlMonitor((pCounter) pCount); + if (pCount->pDriv->eMode == ePreset) { + slaveMode = eTimer; + slavePreset = oneYear; + } else { + slaveMode = pCount->pDriv->eMode; + slavePreset = pCount->pDriv->fPreset; + } for (i = 0; i < self->nSlaves; i++) { - ReleaseCountLock(self->slaves[i]); - self->slaves[i]->SetCountParameters(self->slaveData[i], - pCount->pDriv->fPreset, - pCount->pDriv->eMode); + ReleaseCountLock(self->slaves[i]); + if (i == controlMonitor) { + self->slaves[i]->SetCountParameters(self->slaveData[i], + pCount->pDriv->fPreset, + pCount->pDriv->eMode); + } else { + self->slaves[i]->SetCountParameters(self->slaveData[i], + slavePreset, slaveMode); + } status = self->slaves[i]->StartCount(self->slaveData[i], pCon); if (status != OKOK) { MMCCHalt(pData); @@ -112,10 +128,18 @@ static int MMCCStart(void *pData, SConnection * pCon) /*-------------------------------------------------------------------------*/ static int MMCCStatus(void *pData, SConnection * pCon) { - int status, i; + int status, ctrStatus, i, controlMonitor; + pCounter pCountController = NULL, pSlaveCounter = NULL; pCounter pCount = NULL, pMaster = NULL;; pMultiCounter self = NULL; pDummy pDum = NULL; + enum { + eIdle, + eBusy, + ePause, + eNoBeam, + eFault + } statusLevel; pCount = (pCounter) pData; if (pCount != NULL) { @@ -132,6 +156,44 @@ static int MMCCStatus(void *pData, SConnection * pCon) status = self->slaves[0]->CheckCountStatus(self->slaveData[0], pCon); pMaster = (pCounter)self->slaveData[0]; pCount->pDriv->fLastCurrent = GetControlValue(pMaster); + controlMonitor = GetControlMonitor((pCounter) pCount); + pCountController = (pCounter) self->slaveData[controlMonitor]; + + /* counter states = HWIdle, HWBusy, HWPause, HWNoBeam, HWFault */ + status = HWIdle; + statusLevel = eIdle; + for (i = 0; i < self->nSlaves; i++) { + pSlaveCounter = (pCounter) self->slaveData[i]; + ctrStatus = self->slaves[i]->CheckCountStatus(pSlaveCounter, pCon); + if (statusLevel >= eFault) + continue; + switch (ctrStatus) { + case HWFault: + statusLevel = eFault; + status = HWFault; + break; + case HWNoBeam: + if (statusLevel < eNoBeam) + statusLevel = eNoBeam; + status = HWNoBeam; + break; + case HWPause: + if (statusLevel < ePause) + statusLevel = ePause; + status = HWPause; + break; + default: + if (pCountController->pDriv->eMode == ePreset && i == controlMonitor + && ctrStatus == HWIdle) { + statusLevel = eBusy; /* Allow transition to HWPause or higher */ + status = HWIdle; + } else if (statusLevel < eBusy && ctrStatus != HWIdle) { + /* ffr: We expect !HWIdle means HWBusy, if not the existing code should handle the exception */ + statusLevel = eBusy; + status = ctrStatus; + } + } + } if (status == HWIdle || status == HWFault) { /* stop counting on slaves when finished or when an error @@ -231,7 +293,8 @@ static void loadCountData(pCounter pCount, const char *data) pPtr = (char *) data; pPtr = getNextMMCCNumber(pPtr, pNumber); - pCount->pDriv->fTime = atof(pNumber); + // SICS-195 get time from controlling monitor + // pCount->pDriv->fTime = atof(pNumber); while (pPtr != NULL && i < MAXCOUNT) { pPtr = getNextMMCCNumber(pPtr, pNumber); pCount->pDriv->lCounts[i] = atoi(pNumber); @@ -245,14 +308,19 @@ static int MMCCTransfer(void *pData, SConnection * pCon) int i, retVal = OKOK, status; char pBueffel[132]; pCounter pCount = NULL; + pCounter pCountController = NULL, pCountSlave; pMultiCounter self = NULL; int tclStatus; + int controlMonitor; + double avCntRt; pCount = (pCounter) pData; if (pCount != NULL) { self = (pMultiCounter) pCount->pDriv->pData; } assert(self); + controlMonitor = GetControlMonitor(pCount); + pCountController = (pCounter) self->slaveData[controlMonitor]; for (i = 0; i < self->nSlaves; i++) { status = self->slaves[i]->TransferData(self->slaveData[i], pCon); @@ -261,8 +329,18 @@ static int MMCCTransfer(void *pData, SConnection * pCon) snprintf(pBueffel,sizeof(pBueffel)-1, "WARNING: slave histogram %d failed to transfer data", i); SCWrite(pCon, pBueffel, eWarning); + } else if (pCountController->pDriv->eMode == ePreset) { + if (i != controlMonitor) { + pCountSlave = (pCounter) self->slaveData[i]; + avCntRt = + pCountSlave->pDriv->lCounts[0] / pCountSlave->pDriv->fTime; + pCountSlave->pDriv->lCounts[0] = + avCntRt * pCountController->pDriv->fTime; + pCountSlave->pDriv->fTime = pCountController->pDriv->fTime; + } } } + pCount->pDriv->fTime = pCountController->pDriv->fTime; if (self->transferScript != NULL) { MacroPush(pCon); tclStatus = Tcl_Eval(InterpGetTcl(pServ->pSics), self->transferScript); @@ -302,74 +380,74 @@ static void MMCCParameter(void *pData, float fPreset, CounterMode eMode) static int MultiCounterSet(struct __COUNTER *pCount, char *name, int iCter, float fVal) { - pDummy pDum; - int i; - pMultiCounter self = NULL; - pCounter pCter; - - self = (pMultiCounter) pCount->pData; - assert(self); + pDummy pDum; + int i; + pMultiCounter self = NULL; + pCounter pCter; - for (i = 0; i < self->nSlaves; i++) { - pDum = (pDummy)self->slaveData[i]; - if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){ - pCter = (pCounter)self->slaveData[i]; - if(pCter->pDriv != NULL){ - return pCter->pDriv->Set(pCter->pDriv, name, iCter, fVal); - } else { - return 0; - } - } - } - return 0; + self = (pMultiCounter) pCount->pData; + assert(self); + + for (i = 0; i < self->nSlaves; i++) { + pDum = (pDummy)self->slaveData[i]; + if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){ + pCter = (pCounter)self->slaveData[i]; + if(pCter->pDriv != NULL){ + return pCter->pDriv->Set(pCter->pDriv, name, iCter, fVal); + } else { + return 0; + } + } + } + return 0; } /*-----------------------------------------------------------------------*/ static int MultiCounterGet(struct __COUNTER *pCount, char *name, int iCter, float *fVal) { - pDummy pDum; - int i; - pMultiCounter self = NULL; - pCounter pCter; - pHdb node; - hdbValue v; - - self = (pMultiCounter) pCount->pData; - assert(self); + pDummy pDum; + int i; + pMultiCounter self = NULL; + pCounter pCter; + pHdb node; + hdbValue v; - for (i = 0; i < self->nSlaves; i++) { - pDum = (pDummy)self->slaveData[i]; - if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){ - pCter = (pCounter)self->slaveData[i]; - if(pCter->pDriv != NULL){ - return pCter->pDriv->Get(pCter->pDriv, name, iCter, fVal); - } else { - return 0; - } - } - } - return 0; + self = (pMultiCounter) pCount->pData; + assert(self); + + for (i = 0; i < self->nSlaves; i++) { + pDum = (pDummy)self->slaveData[i]; + if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){ + pCter = (pCounter)self->slaveData[i]; + if(pCter->pDriv != NULL){ + return pCter->pDriv->Get(pCter->pDriv, name, iCter, fVal); + } else { + return 0; + } + } + } + return 0; } /*-----------------------------------------------------------------------*/ static int MultiCounterSend(struct __COUNTER *pCount, char *pText, char *reply, int replylen) { - pDummy pDum; - int i; - pMultiCounter self = NULL; - pCounter pCter; - - self = (pMultiCounter) pCount->pData; - assert(self); + pDummy pDum; + int i; + pMultiCounter self = NULL; + pCounter pCter; - for (i = 0; i < self->nSlaves; i++) { - pDum = (pDummy)self->slaveData[i]; - if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){ - pCter = (pCounter)self->slaveData[i]; - return pCter->pDriv->Send(pCter->pDriv,pText, reply, replylen); - } - } - return 0; + self = (pMultiCounter) pCount->pData; + assert(self); + + for (i = 0; i < self->nSlaves; i++) { + pDum = (pDummy)self->slaveData[i]; + if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){ + pCter = (pCounter)self->slaveData[i]; + return pCter->pDriv->Send(pCter->pDriv,pText, reply, replylen); + } + } + return 0; } /*---------------------------------------------------------------------*/ static int MultiCounterError(struct __COUNTER *pDriv, int *iCode, @@ -461,6 +539,30 @@ int MakeMultiCounter(SConnection * pCon, SicsInterp * pSics, pDriv->pData = self; pDriv->KillPrivate = KillMultiDriver; pDriv->iNoOfMonitors = MAXCOUNT; + /* + now loop through the remaining arguments, thereby entering them into + the slave list. + */ + self->nSlaves = 0; + for (i = 2; i < argc; i++) { + pCom = FindCommand(pSics, argv[i]); + if (!pCom) { + snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: object %s not found in MakeMultiCounter", + argv[i]); + SCWrite(pCon, pBueffel, eError); + continue; + } + pCount = GetCountableInterface(pCom->pData); + if (!pCount) { + snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: object %s is NOT countable", argv[i]); + SCWrite(pCon, pBueffel, eError); + continue; + } + self->slaves[self->nSlaves] = pCount; + self->slaveData[self->nSlaves] = pCom->pData; + self->nSlaves++; + } + pDriv->iNoOfMonitors = self->nSlaves; pNew = CreateCounter(argv[1], pDriv); if (pNew == NULL) { SCWrite(pCon, "ERROR: out of memory in MakeMultiCounter", eError); @@ -483,29 +585,6 @@ int MakeMultiCounter(SConnection * pCon, SicsInterp * pSics, pNew->pCountInt->TransferData = MMCCTransfer; pNew->pCountInt->SetCountParameters = MMCCParameter; - /* - now loop through the remaining arguments, thereby entering them into - the slave list. - */ - for (i = 2; i < argc; i++) { - pCom = FindCommand(pSics, argv[i]); - if (!pCom) { - snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: object %s not found in MakeMultiCounter", - argv[i]); - SCWrite(pCon, pBueffel, eError); - continue; - } - pCount = GetCountableInterface(pCom->pData); - if (!pCount) { - snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: object %s is NOT countable", argv[i]); - SCWrite(pCon, pBueffel, eError); - continue; - } - self->slaves[self->nSlaves] = pCount; - self->slaveData[self->nSlaves] = pCom->pData; - self->nSlaves++; - } - /* now install our action command and we are done */