Ferdi's fixes

This commit is contained in:
Douglas Clowes
2012-11-29 11:42:44 +11:00
parent 33e0fada7c
commit 8e185c6291

View File

@@ -77,9 +77,12 @@ static int MMCCHalt(void *pData)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static int MMCCStart(void *pData, SConnection * pCon) static int MMCCStart(void *pData, SConnection * pCon)
{ {
int i, status; int i, status, controlMonitor;
int slavePreset, oneYear = 32000000;
pCounter pCount = NULL; pCounter pCount = NULL;
pMultiCounter self = NULL; pMultiCounter self = NULL;
char buffer[128];
CounterMode slaveMode;
pCount = (pCounter) pData; pCount = (pCounter) pData;
if (pCount != NULL) { if (pCount != NULL) {
@@ -90,12 +93,25 @@ static int MMCCStart(void *pData, SConnection * pCon)
if (!GetCountLock(pCount->pCountInt, pCon)) { if (!GetCountLock(pCount->pCountInt, pCon)) {
return HWFault; 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++) { for (i = 0; i < self->nSlaves; i++) {
ReleaseCountLock(self->slaves[i]); ReleaseCountLock(self->slaves[i]);
self->slaves[i]->SetCountParameters(self->slaveData[i], if (i == controlMonitor) {
pCount->pDriv->fPreset, self->slaves[i]->SetCountParameters(self->slaveData[i],
pCount->pDriv->eMode); 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); status = self->slaves[i]->StartCount(self->slaveData[i], pCon);
if (status != OKOK) { if (status != OKOK) {
MMCCHalt(pData); MMCCHalt(pData);
@@ -112,10 +128,18 @@ static int MMCCStart(void *pData, SConnection * pCon)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static int MMCCStatus(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;; pCounter pCount = NULL, pMaster = NULL;;
pMultiCounter self = NULL; pMultiCounter self = NULL;
pDummy pDum = NULL; pDummy pDum = NULL;
enum {
eIdle,
eBusy,
ePause,
eNoBeam,
eFault
} statusLevel;
pCount = (pCounter) pData; pCount = (pCounter) pData;
if (pCount != NULL) { if (pCount != NULL) {
@@ -132,6 +156,44 @@ static int MMCCStatus(void *pData, SConnection * pCon)
status = self->slaves[0]->CheckCountStatus(self->slaveData[0], pCon); status = self->slaves[0]->CheckCountStatus(self->slaveData[0], pCon);
pMaster = (pCounter)self->slaveData[0]; pMaster = (pCounter)self->slaveData[0];
pCount->pDriv->fLastCurrent = GetControlValue(pMaster); 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) { if (status == HWIdle || status == HWFault) {
/* /*
stop counting on slaves when finished or when an error 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 = (char *) data;
pPtr = getNextMMCCNumber(pPtr, pNumber); 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) { while (pPtr != NULL && i < MAXCOUNT) {
pPtr = getNextMMCCNumber(pPtr, pNumber); pPtr = getNextMMCCNumber(pPtr, pNumber);
pCount->pDriv->lCounts[i] = atoi(pNumber); pCount->pDriv->lCounts[i] = atoi(pNumber);
@@ -245,14 +308,19 @@ static int MMCCTransfer(void *pData, SConnection * pCon)
int i, retVal = OKOK, status; int i, retVal = OKOK, status;
char pBueffel[132]; char pBueffel[132];
pCounter pCount = NULL; pCounter pCount = NULL;
pCounter pCountController = NULL, pCountSlave;
pMultiCounter self = NULL; pMultiCounter self = NULL;
int tclStatus; int tclStatus;
int controlMonitor;
double avCntRt;
pCount = (pCounter) pData; pCount = (pCounter) pData;
if (pCount != NULL) { if (pCount != NULL) {
self = (pMultiCounter) pCount->pDriv->pData; self = (pMultiCounter) pCount->pDriv->pData;
} }
assert(self); assert(self);
controlMonitor = GetControlMonitor(pCount);
pCountController = (pCounter) self->slaveData[controlMonitor];
for (i = 0; i < self->nSlaves; i++) { for (i = 0; i < self->nSlaves; i++) {
status = self->slaves[i]->TransferData(self->slaveData[i], pCon); 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, snprintf(pBueffel,sizeof(pBueffel)-1,
"WARNING: slave histogram %d failed to transfer data", i); "WARNING: slave histogram %d failed to transfer data", i);
SCWrite(pCon, pBueffel, eWarning); 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) { if (self->transferScript != NULL) {
MacroPush(pCon); MacroPush(pCon);
tclStatus = Tcl_Eval(InterpGetTcl(pServ->pSics), self->transferScript); 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, static int MultiCounterSet(struct __COUNTER *pCount, char *name,
int iCter, float fVal) int iCter, float fVal)
{ {
pDummy pDum; pDummy pDum;
int i; int i;
pMultiCounter self = NULL; pMultiCounter self = NULL;
pCounter pCter; pCounter pCter;
self = (pMultiCounter) pCount->pData; self = (pMultiCounter) pCount->pData;
assert(self); assert(self);
for (i = 0; i < self->nSlaves; i++) { for (i = 0; i < self->nSlaves; i++) {
pDum = (pDummy)self->slaveData[i]; pDum = (pDummy)self->slaveData[i];
if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){ if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){
pCter = (pCounter)self->slaveData[i]; pCter = (pCounter)self->slaveData[i];
if(pCter->pDriv != NULL){ if(pCter->pDriv != NULL){
return pCter->pDriv->Set(pCter->pDriv, name, iCter, fVal); return pCter->pDriv->Set(pCter->pDriv, name, iCter, fVal);
} else { } else {
return 0; return 0;
} }
} }
} }
return 0; return 0;
} }
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static int MultiCounterGet(struct __COUNTER *pCount, char *name, static int MultiCounterGet(struct __COUNTER *pCount, char *name,
int iCter, float *fVal) int iCter, float *fVal)
{ {
pDummy pDum; pDummy pDum;
int i; int i;
pMultiCounter self = NULL; pMultiCounter self = NULL;
pCounter pCter; pCounter pCter;
pHdb node; pHdb node;
hdbValue v; hdbValue v;
self = (pMultiCounter) pCount->pData; self = (pMultiCounter) pCount->pData;
assert(self); assert(self);
for (i = 0; i < self->nSlaves; i++) { for (i = 0; i < self->nSlaves; i++) {
pDum = (pDummy)self->slaveData[i]; pDum = (pDummy)self->slaveData[i];
if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){ if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){
pCter = (pCounter)self->slaveData[i]; pCter = (pCounter)self->slaveData[i];
if(pCter->pDriv != NULL){ if(pCter->pDriv != NULL){
return pCter->pDriv->Get(pCter->pDriv, name, iCter, fVal); return pCter->pDriv->Get(pCter->pDriv, name, iCter, fVal);
} else { } else {
return 0; return 0;
} }
} }
} }
return 0; return 0;
} }
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static int MultiCounterSend(struct __COUNTER *pCount, char *pText, static int MultiCounterSend(struct __COUNTER *pCount, char *pText,
char *reply, int replylen) char *reply, int replylen)
{ {
pDummy pDum; pDummy pDum;
int i; int i;
pMultiCounter self = NULL; pMultiCounter self = NULL;
pCounter pCter; pCounter pCter;
self = (pMultiCounter) pCount->pData; self = (pMultiCounter) pCount->pData;
assert(self); assert(self);
for (i = 0; i < self->nSlaves; i++) { for (i = 0; i < self->nSlaves; i++) {
pDum = (pDummy)self->slaveData[i]; pDum = (pDummy)self->slaveData[i];
if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){ if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){
pCter = (pCounter)self->slaveData[i]; pCter = (pCounter)self->slaveData[i];
return pCter->pDriv->Send(pCter->pDriv,pText, reply, replylen); return pCter->pDriv->Send(pCter->pDriv,pText, reply, replylen);
} }
} }
return 0; return 0;
} }
/*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/
static int MultiCounterError(struct __COUNTER *pDriv, int *iCode, static int MultiCounterError(struct __COUNTER *pDriv, int *iCode,
@@ -461,6 +539,30 @@ int MakeMultiCounter(SConnection * pCon, SicsInterp * pSics,
pDriv->pData = self; pDriv->pData = self;
pDriv->KillPrivate = KillMultiDriver; pDriv->KillPrivate = KillMultiDriver;
pDriv->iNoOfMonitors = MAXCOUNT; 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); pNew = CreateCounter(argv[1], pDriv);
if (pNew == NULL) { if (pNew == NULL) {
SCWrite(pCon, "ERROR: out of memory in MakeMultiCounter", eError); 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->TransferData = MMCCTransfer;
pNew->pCountInt->SetCountParameters = MMCCParameter; 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 now install our action command and we are done
*/ */