diff --git a/devexec.c b/devexec.c index c6016277..9c7fd293 100644 --- a/devexec.c +++ b/devexec.c @@ -859,7 +859,8 @@ int DevExecTask(void *pData) { pExeList self = NULL; - int iRet; + char pBueffel[132], pInterrupt[80]; + int iRet, iInterrupt; self = (pExeList)pData; @@ -875,11 +876,17 @@ switch(iRet) { case -1: /* some problem */ - if(SCGetInterrupt(self->pOwner) != eContinue) + iInterrupt = SCGetInterrupt(self->pOwner); + if(iInterrupt != eContinue) { - SCWrite(self->pOwner,"ERROR: aborting operation due to HW problem", - eError); + SCWrite(self->pOwner,pBueffel, eError); + if(iInterrupt > 1) + { + Interrupt2Text(iInterrupt,pInterrupt,79); + snprintf(pBueffel,131,"ERROR: interrupt %s triggered", + pInterrupt); StopExe(self,"all"); + } #ifdef DEBUG printf("DevExecTask found an error\n"); #endif diff --git a/motor.c b/motor.c index 27f5838f..dd153064 100644 --- a/motor.c +++ b/motor.c @@ -200,8 +200,141 @@ SCSetInterrupt(pCon,iVal); } } -/*-----------------------------------------------------------------------*/ +/*---------------------------------------------------------------------*/ +static int statusRunTo(pMotor self, SConnection *pCon) +{ + char pBueffel[256]; + + if(self->retryCount >= ObVal(self->ParArray,POSCOUNT)) + { + snprintf(pBueffel,255,"ERROR: aborting motor %s after %d retries", + self->name, (int)ObVal(self->ParArray,POSCOUNT)); + SCWrite(pCon,pBueffel,eError); + return HWFault; + } + self->retryCount++; + snprintf(pBueffel,255,"WARNING: restarting %s, %d time", + self->name,self->retryCount); + SCWrite(pCon,pBueffel,eWarning); + self->pDriver->RunTo(self->pDriver,self->fTarget); + return HWBusy; +} +/*--------------------------------------------------------------------*/ +static int checkPosition(pMotor self, SConnection *pCon) +{ + float fHard; + char pBueffel[132]; + int status; + + MotorGetHardPosition(self,pCon,&fHard); + self->fPosition = fHard; + if(absf(fHard - self->fTarget) > ObVal(self->ParArray,PREC)) + { + snprintf(pBueffel,131,"WARNING: %s off position by %f", + self->name, absf(fHard - self->fTarget)); + SCWrite(pCon,pBueffel, eWarning); + status = statusRunTo(self,pCon); + return status; + } + return HWIdle; +} +/*--------------------------------------------------------------------*/ +static void finishDriving(pMotor self, SConnection *pCon) +{ + MotCallback sCall; + MotorGetSoftPosition(self,pCon,&sCall.fVal); + sCall.pName = self->name; + InvokeCallBack(self->pCall, MOTEND, &sCall); +} +/*--------------------------------------------------------------------*/ +static int reportAndFixError(pMotor self, SConnection *pCon) +{ + char pBueffel[256], pError[131]; + int iCode, iRet, newStatus; + + self->pDriver->GetError(self->pDriver,&iCode, pError,131); + iRet = self->pDriver->TryAndFixIt(self->pDriver,iCode, self->fTarget); + switch(iRet) + { + case MOTFAIL: + snprintf(pBueffel,255,"ERROR: %s on %s",pError,self->name); + SCWrite(pCon,pBueffel,eError); + newStatus = HWFault; + break; + case MOTREDO: + newStatus = statusRunTo(self,pCon); + break; + case MOTOK: + newStatus = HWIdle; + break; + default: + SCWrite(pCon,"WARNING: bad status code in motor.c:reportAndFixError", + eWarning); + SCWrite(pCon,"You may continue, but show this to a SICS programmer", + eWarning); + newStatus = HWIdle; + break; + } + return newStatus; +} +/*--------------------------------------------------------------------- + New version, refactored October 2003 + -----------------------------------------------------------------------*/ static int evaluateStatus(pMotor self, SConnection *pCon) +{ + int iRet, iCode, newStatus; + MotCallback sCall; + char pBueffel[256], pError[132]; + float fHard; + + iRet = self->pDriver->GetStatus(self->pDriver); + newStatus = iRet; + switch(iRet) + { + case OKOK: + case HWIdle: + newStatus = checkPosition(self,pCon); + if(newStatus != HWBusy) + { + finishDriving(self,pCon); + } + break; + case HWFault: + newStatus = reportAndFixError(self,pCon); + break; + case HWPosFault: + newStatus = reportAndFixError(self,pCon); + if(newStatus == HWFault && ObVal(self->ParArray,IGNOREFAULT) < 1) + { + newStatus = HWPosFault; + } + break; + case HWBusy: + newStatus = HWBusy; + break; + case HWWarn: + self->pDriver->GetError(self->pDriver,&iCode, pError,131); + snprintf(pBueffel,255,"WARNING: motor reported: %s", pError); + SCWrite(pCon,pBueffel,eWarning); + newStatus = HWIdle; + break; + default: + SCWrite(pCon,"WARNING: Bad status in motor.c:evaluatStatus",eWarning); + SCWrite(pCon,"You may continue, but show this to a SICS programmer", + eWarning); + break; + } + if(newStatus == HWFault) + { + MotorInterrupt(pCon,ObVal(self->ParArray,INT)); + self->retryCount = 0; + } + return newStatus; +} +/*----------------------------------------------------------------------- + old version, kept for time being. + ----------------------------------------------------------------------*/ +static int eevaluateStatus(pMotor self, SConnection *pCon) { int iRet, iCode; MotCallback sCall; @@ -269,7 +402,7 @@ static int evaluateStatus(pMotor self, SConnection *pCon) return HWBusy; } } - /* a positioning fault */ + /* a positioning fault */ else if(iRet == HWPosFault) { self->pDriver->GetError(self->pDriver,&iCode, pError,131); @@ -388,7 +521,7 @@ static void handleMoveCallback(pMotor self, SConnection *pCon) ObParInit(pM->ParArray,SPEED,"speed",0.02,usInternal); ObParInit(pM->ParArray,SIGN,"sign",1.0,usMugger); ObParInit(pM->ParArray,ECOUNT,"failafter",3.0,usMugger); - ObParInit(pM->ParArray,POSCOUNT,"poscount",20.0,usMugger); + ObParInit(pM->ParArray,POSCOUNT,"maxretry",3.0,usMugger); ObParInit(pM->ParArray,IGNOREFAULT,"ignorefault",0.0,usMugger); pDriv->GetPosition(pDriv,&(pM->fPosition)); pM->fTarget = pM->fPosition; diff --git a/scan.c b/scan.c index 6f88432e..b71fdbb1 100644 --- a/scan.c +++ b/scan.c @@ -1236,6 +1236,9 @@ int StoreScanCounts(pScanData self, char *data) break; case eAbortOperation: SCSetInterrupt(self->pCon,eContinue); + SCWrite(self->pCon, + "WARNING: skipped scan point due to motor failure", + eWarning); continue; break; case eAbortScan: